libsheepy
libsheepy.h
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2023 Remy Noulin
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #ifndef _libsheepyH
24 #define _libsheepyH
25 // libsheepy
26 // can't use #pragma once for some reason (gcc 4.9), compilation fails
27 
28 #ifndef _GNU_SOURCE
29 #define _GNU_SOURCE
30 #endif // _GNU_SOURCE
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <stdio.h>
34 #include <stdint.h>
35 #include <stdbool.h>
36 #include <stdlib.h>
37 #include <ctype.h>
38 #ifdef __GNUC__
39 #if !defined(__arm__) && !defined(__aarch64__)
40 #include <immintrin.h>
41 #endif // #if !defined(__arm__) && !defined(__aarch64__)
42 #endif // __GNUC__
43 #include <time.h>
44 #include <setjmp.h>
45 #ifdef __TINYC__
46 #define and &&
47 #define or ||
48 #define not !
49 #else
50 #include <iso646.h> /* and or not defines */
51 #endif
52 #include <inttypes.h> /* for PRIu64 in stopwatchLog */
53 #include <unistd.h> /* for sleep,... */
54 #include <string.h> /* for strerror */
55 #include <errno.h>
56 
99 // version accoring to the version package: Release.Major.minor.patch
100 // https://noulin.net/version/file/README.md.html
101 #define LIBSHEEPY_VERSION "2.2.12.1"
102 
103 #ifndef SH_PREFIX
104 #define SH_PREFIX(NAME) NAME
105 #endif
106 
107 // libsheepy API Header file _libsheepyH
108 
110 #define internal static
111 
113 #define local static
114 
116 #define var __auto_type
117 
119 #undef TRUE /* avoid conflict with ncurses */
120 extern const bool TRUE;
122 #undef FALSE /* avoid conflict with ncurses */
123 extern const bool FALSE;
124 
126 #define null NULL
127 #define yes true
128 #define on true
129 #define no false
130 #define off false
131 
133 #define boolS(x) x ? "TRUE" : "FALSE"
134 
138 #define XSUCCESS exit(EXIT_SUCCESS);
139 #define XSuccess XSUCCESS
140 
144 #define XFAILURE exit(EXIT_FAILURE);
145 #define XFailure XFAILURE
146 
152 #define logXSuccess(string) MACRO(\
153  logP("Success: %s", string);\
154  XSuccess;\
155  )
156 
164 #define logXSuccessf(format, ...) MACRO(\
165  logP(format, __VA_ARGS__);\
166  XSuccess;\
167  )
168 
174 #define logXFailure(string) MACRO(\
175  logC("Failed: %s", string);\
176  XFailure;\
177  )
178 
186 #define logXFailuref(format, ...) MACRO(\
187  logC(format, __VA_ARGS__);\
188  XFailure;\
189  )
190 
196 #define logExit(exitCode, string) MACRO (\
197  logI("Exit: %s", string);\
198  exit(exitCode);\
199  )
200 
206 #define exitFailure(cond) \
207  if (!cond) \
208  exit(EXIT_FAILURE);
209 
210 
233 #define procbegin do{
234 #define procend }while(0)
235 #define funcbegin ({
236 #define funcend })
237 
243 #define MACRO( STATEMENTS ) do { STATEMENTS } while(0)
244 
253 #define FUNC( STATEMENTS) ({ STATEMENTS })
254 
265 #define is =
266 #define equals ==
267 #define nequal !=
268 #define shr >>
269 #define shl <<
270 #define inc ++
271 #define dec --
272 #define ptr_to &
273 #define val_of *
274 
282 #define stringifyExpr(expr) stringifyExpr1(expr)
283 /* Double-indirection required to stringify expansions */
284 #define stringifyExpr1(expr) #expr
285 
286 // libsheepy uses bit 63 in logMask
287 // to disable log prints from libsheepy, add:
288 // logMask &= (~libsheepyErrorMask);
289 // or
290 // disableLibsheepyErrorLogs;
291 #define libsheepyErrorMask 0x8000000000000000UL
292 
293 #define disableLibsheepyErrorLogs do{logMask &= (~libsheepyErrorMask);}while(0)
294 
295 #define shperror(string) procbegin\
296  char *errstr = strerror(errno);\
297  logE("%s: %s", string, errstr);\
298  procend
299 
306 #define pFuncError do{ if ((libsheepyErrorMask) & logMask) { shperror(__func__);logEBtrace;} }while(0);
307 
311 #define pStrError(str) do{ if ((libsheepyErrorMask) & logMask) { shperror(str);logEBtrace;} }while(0);
312 
319 #define shPrintError do{ if ((libsheepyErrorMask) & logMask) { logE("Error line "stringifyExpr(__LINE__)", function %s, file "__FILE__"\n", __func__); logEBtrace;} }while(0);
320 
324 #define pError(func) if (func == -1) shPrintError
325 
329 #define pError0(func) if (func == 0) shPrintError
330 
334 #define pErrorNot0(func) if (func != 0) shPrintError
335 
339 #define pErrorNULL(func) if (func == NULL) shPrintError
340 
344 #define pErrorValue(func, errorValue) if (func == errorValue) shPrintError
345 
349 #define pTestError(test) if (test) shPrintError
350 
354 #define pTestErrorCmd(test, cmd) if (test) { shPrintError cmd; }
355 
359 #define pErrorCmd(func, test, cmd) if (func test) { shPrintError cmd; }
360 
367 #define pErrorResult(result, func, test) if ((result = func) test) shPrintError
368 
375 #define pErrorResultCmd(result, func, test, cmd) if ((result = func) test) { shPrintError cmd; }
376 
386 #define isError(assigned, left) if (!(assigned = left))
387 
391 #define maxTryThrowCount 16
392 extern jmp_buf tryJumpBuffers[maxTryThrowCount];
393 
397 #define setJump(slot) setjmp(tryJumpBuffers[slot])
398 
414 #define try(slot) if (!setjmp(tryJumpBuffers[slot]))
415 
419 #define throw(slot) longjmp(tryJumpBuffers[slot], 1)
420 
428 #define tryV(result, slot) if (!(result = setjmp(tryJumpBuffers[slot])))
429 
433 #define throwV(slot, value) longjmp(tryJumpBuffers[slot], value)
434 
435 // limited use macro - for test only
436 #define goNLabel(go, label) goto go; label:
437 
441 #define i8 int8_t
442 #define i16 int16_t
443 #define i32 int32_t
444 #define i64 int64_t
445 #define u8 uint8_t
446 #define u16 uint16_t
447 #define u32 uint32_t
448 #define u64 uint64_t
449 #define f32 float
450 #define f64 double
451 
455 #define I8(value) (i8)(value)
456 #define I16(value) (i16)(value)
457 #define I32(value) (i32)(value)
458 #define I64(value) (i64)(value)
459 #define U8(value) (u8)(value)
460 #define U16(value) (u16)(value)
461 #define U32(value) (u32)(value)
462 #define U64(value) (u64)(value)
463 #define F32(value) (f32)(value)
464 #define F64(value) (f64)(value)
465 
466 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
467 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
468 #define MIN3(a, b, c) MIN((typeof(a))MIN(a, b), c)
469 #define MAX3(a, b, c) MAX((typeof(a))MAX(a, b), c)
470 #define ABS(a) (((a) < 0) ? -(a) : (a))
471 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
472 #define COUNT_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))
473 #define ARRAY_SIZE COUNT_ELEMENTS
474 
478 #define EXTRACT(x, msb, lsb) ((~(0xFFFFFFFFFFFFFFFEUL << (msb)) & (x)) >> (lsb))
479 
489 #define CMP(a, b) ({\
490  var UNIQVAR(_a) = a;\
491  var UNIQVAR(_b) = b;\
492  UNIQVAR(_a) > UNIQVAR(_b) ? 1 : UNIQVAR(_a) < UNIQVAR(_b) ? -1 : 0;\
493  })
494 
501 #define init0Var {0}
502 
506 #define ZEROVAR(name) zeroBuf(&(name), sizeof(name))
507 
519 #define BUCKETS(count, divider) ((count)/(divider) + (((count) % (divider)) ? 1 : 0))
520 
524 #define swapV(a, b) do{\
525  var UNIQVAR(swaptmp) = a;\
526  a = b;\
527  b = UNIQVAR(swaptmp);\
528  } while(0)
529 
531 #define setMax(result, a, b) do{\
532  var UNIQVAR(_a) = a;\
533  var UNIQVAR(_b) = b;\
534  result = MAX(UNIQVAR(_a), UNIQVAR(_b));\
535  } while(0)
536 
538 #define setMin(result, a, b) do{\
539  var UNIQVAR(_a) = a;\
540  var UNIQVAR(_b) = b;\
541  result = MIN(UNIQVAR(_a), UNIQVAR(_b));\
542  } while(0)
543 
545 #define maxV(a, b) ({\
546  var UNIQVAR(_a) = a;\
547  var UNIQVAR(_b) = b;\
548  MAX(UNIQVAR(_a), UNIQVAR(_b));\
549  })
550 
552 #define minV(a, b) ({\
553  var UNIQVAR(_a) = a;\
554  var UNIQVAR(_b) = b;\
555  MIN(UNIQVAR(_a), UNIQVAR(_b));\
556  })
557 
559 #define absV(a) ({var UNIQVAR(_a) = a; ((UNIQVAR(_a)) < 0) ? -(UNIQVAR(_a)) : (UNIQVAR(_a));})
560 
568 #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
569 
571 #define isIntOdd(value) (value&1)
572 
574 #define isIntEven(value) (!(value&1))
575 
579 #define typ typedef
580 
584 #define ret return
585 
589 #define elif else if
590 
599 #define unless(cond) if(not(cond))
600 
611 #define until(cond) while(not(cond))
612 
613 
617 #define cast(type, casted, toCast) type casted = (type) (toCast);
618 
622 #define freen(ptr) do {\
623  free(ptr);\
624  (ptr) = NULL;\
625  } while(0)
626 
642 #define EVA(var, func) (var = func, var)
643 
661 #define loopBreakerInit\
662  uint32_t libsheepyLoopCounter = 0;\
663  bool didBreak = false;
664 
668 #define loopBreakerReset\
669  libsheepyLoopCounter = 0;\
670  didBreak = false;
671 
675 #define loopBreaker(breakCount)\
676  libsheepyLoopCounter++;\
677  if(libsheepyLoopCounter>breakCount){didBreak=true;break;}
678 
684 #define FILE_LINE __FILE__":"stringifyExpr(__LINE__)
685 #define PFILE_LINE puts(FILE_LINE)
686 
694 #define AT pLog(LOG_DEBUG, __FILE__", %s:"stringifyExpr(__LINE__)"\n",__func__);
695 
699 #define TODO(message) logD(BLD MGT BGBLK"TODO"RST BLD MGT": "message RST)
700 
701 // macros for token paste for automatically creating unique variable names
702 // used in forEachCharP
703 #define TOKENPASTE2(a, b) a ## b
704 #define TOKENPASTE(a, b) TOKENPASTE2(a, b)
705 #define UNIQVAR(name) TOKENPASTE(name, __LINE__)
706 
707 
708 // free val when it is out of scope
709 void cleanUpCharFree(char **val);
710 
714 #define cleanCharP(name) char *name CLEANUP(cleanUpCharFree)
715 
716 // free val when it is out of scope
717 void cleanUpListFree(char*** val);
718 
722 #define cleanListP(name) char **name CLEANUP(cleanUpListFree)
723 
724 // free val when it is out of scope
725 void cleanUpFileFree(FILE **val);
726 
730 #define cleanFileP(name) FILE *name CLEANUP(cleanUpFileFree)
731 
732 // close val when it is out of scope
733 void cleanUpFd(int *val);
734 
738 #define cleanFd(name) int name CLEANUP(cleanUpFd)
739 #define cleanFdInit(name) int name CLEANUP(cleanUpFd) = -1
740 
748 #define logVar(var, format) logD("%s=%" format, stringifyExpr(var), var);
749 #define logMVar(mask, var, format) logMD(mask, "%s=%" format, stringifyExpr(var), var);
750 
752 #define logBoolVar(var) logVar(var, "b");
753 #define logMBoolVar(mask, var) logMVar(mask, var, "b");
754 
758 #define logPtr(pointer) logD("%s=%p", stringifyExpr(pointer), pointer);
759 #define logMPtr(mask, pointer) logMD(mask, "%s=%p", stringifyExpr(pointer), pointer);
760 
761 // colors and effects
763 #define RST "\x1B[0m"
764 
765 #define BLD "\x1B[1m"
766 
767 #define FNT "\x1B[2m"
768 
769 #define ITL "\x1B[3m"
770 
771 #define UDL "\x1B[4m"
772 
773 #define BLI "\x1B[5m"
774 
775 #define INV "\x1B[7m"
776 
777 #define COC "\x1B[8m"
778 
779 #define CRD "\x1B[9m"
780 
781 // foreground
783 #define BLK "\x1B[30m"
784 
785 #define RED "\x1B[31m"
786 
787 #define GRN "\x1B[32m"
788 
789 #define YLW "\x1B[33m"
790 
791 #define BLU "\x1B[34m"
792 
793 #define MGT "\x1B[35m"
794 
795 #define CYN "\x1B[36m"
796 
797 #define WHT "\x1B[37m"
798 
799 // background
801 #define BGBLK "\x1B[40m"
802 
803 #define BGRED "\x1B[41m"
804 
805 #define BGGRN "\x1B[42m"
806 
807 #define BGYLW "\x1B[43m"
808 
809 #define BGBLU "\x1B[44m"
810 
811 #define BGMGT "\x1B[45m"
812 
813 #define BGCYN "\x1B[46m"
814 
815 #define BGWHT "\x1B[47m"
816 
817 // bug in cg_c.py
818 #define sheepyRGBFP len = fprintf(stream, "%*s", (int)(info->left ? -info->width : info->width), b)
819 #define sheepyBOOLFP len = fprintf(stream, "%*s", (int)(info->left ? -info->width : info->width), boolS(value))
820 
827 #define timeNs(func) do{\
828  u64 UNIQVAR(endTime);\
829  u64 UNIQVAR(startTime) = getMonotonicTime();\
830  func;\
831  UNIQVAR(endTime) = getMonotonicTime();\
832  printf(BLD GRN "time" RST ": %" PRIu64 "ns " BLD UDL YLW "%s" RST "\n", UNIQVAR(endTime)-UNIQVAR(startTime), stringifyExpr(func));\
833 }while(0)
834 
835 #define TIMEUNITUS "us"
836 #define TIMEUNITMS "ms"
837 #define TIMEUNITSC "s"
838 
845 #define timeDivs(func, div, timeunit) do{\
846  u64 UNIQVAR(endTime);\
847  u64 UNIQVAR(startTime) = getMonotonicTime();\
848  func;\
849  UNIQVAR(endTime) = getMonotonicTime();\
850  printf(BLD GRN "time:" RST " %f"timeunit" " BLD UDL YLW "%s" RST "\n", (f32)(UNIQVAR(endTime)-UNIQVAR(startTime))/div, stringifyExpr(func));\
851 }while(0)
852 
859 #define timeUs(func) timeDivs(func,1E3, TIMEUNITUS)
860 
867 #define timeMs(func) timeDivs(func,1E6, TIMEUNITMS)
868 
875 #define timeSec(func) timeDivs(func,1E9, TIMEUNITSC)
876 
877 // nanosecond stopwatch, the returned value is in ns. op parameter: 0 to start, 1 to get the stopwatch value
878 uint64_t shStopwatch(uint8_t op);
879 
880 #define stopwatchStart shStopwatch(0)
881 
885 #define stopwatchLog printf(BLD GRN "time" RST ": %" PRIu64 "ns\n", shStopwatch(1))
886 
890 #define stopwatchLogDivs(div, timeunit) printf(BLD GRN "time" RST ": %f"timeunit"\n", ((float)shStopwatch(1))/div)
891 
895 #define stopwatchLogUs stopwatchLogDivs(1E3, TIMEUNITUS)
896 
900 #define stopwatchLogMs stopwatchLogDivs(1E6, TIMEUNITMS)
901 
905 #define stopwatchLogSec stopwatchLogDivs(1E9, TIMEUNITSC)
906 
912 #define LOG_EMERGENCY 0
913 #define LOG_ALERT 1
914 #define LOG_CRITICAL 2
915 #define LOG_ERROR 3
916 #ifdef LOG_WARNING
917 #undef LOG_WARNING // conflict with syslog.h
918 #endif
919 #define LOG_WARNING 4
920 #define LOG_NOTICE 5
921 #define LOG_PASS 6
922 #ifdef LOG_INFO
923 #undef LOG_INFO // conflict with syslog.h
924 #endif
925 #define LOG_INFO 7
926 #define LOG_DEBUG 8
927 #define LOG_INVALID 9
928 #define LOG_MAX_LEVEL LOG_INVALID
929 
931 #define LOG_DISABLE -1
932 
941 #define LOG_VERBOSE 0
942 
946 #define LOG_CONCISE 1
947 
951 #define LOG_DATE 2 // default
952 
956 #define LOG_FUNC 3
957 
961 #define LOG_PROG 4
962 
966 #define LOG_PROGNDATE 5
967 
971 #define LOG_VOID 6
972 
976 #define LOG_UTF8 7
977 
981 #define LOG_PROGNFUNC 8
982 
986 #define LOG_INVALID_MODE 9
987 
988 // add a log file, maximum 15 files
989 FILE *SH_PREFIX(setLogFile)(char *filename);
990 #define openLogFile setLogFile
991 
992 #ifdef __GNUC__
993 
997 #define MUST_CHECK __attribute__ ((warn_unused_result))
998 #else
999 #define MUST_CHECK
1000 #endif
1001 
1002 // current log symbols
1003 int getLogSymbols(void) MUST_CHECK;
1004 
1005 // set log symbols, LOG_VERBOSE for words, LOG_UTF8 for emojis, LOG_VOID for no symbols, LOG_INVALID_MODE (reset log symbols) for default log mode symbols, anything else (LOG_CONCISE,...) for symbols (!*+->~)
1006 void setLogSymbols(int mode);
1007 
1008 // current max log level
1009 int getMaxLogLevel(void) MUST_CHECK;
1010 
1011 // set max log level, logs above logMaxLevel are skipped
1012 void setMaxLogLevel(int logLevel);
1013 
1014 // close logfiles opened with setLogFile
1015 void closeLogFiles(void);
1016 
1017 // get current log mode (LOG_VERBOSE, LOG_CONCISE, ...)
1018 int getLogMode(void) MUST_CHECK;
1019 
1020 // set log mode LOG_VERBOSE, LOG_CONCISE, ...
1021 void setLogMode(int mode);
1022 
1023 // get current log long/short path value, default is TRUE (short paths)
1024 bool getLogShortPath(void) MUST_CHECK;
1025 
1026 // set log long/short file path value for VERBOSE mode
1027 void setLogShortPath(bool shortPath);
1028 
1029 // get stdout state, when TRUE (default) all logs are printed to stdout
1030 bool getLogStdout(void) MUST_CHECK;
1031 
1032 // enable/disable printing logs to stdout
1033 void setLogStdout(bool state);
1034 
1035 // log to a file named progName.log
1036 bool openProgLogFile(void) MUST_CHECK;
1037 
1038 // keep ansi colors in logs
1039 void keepAnsiColorsInLog(bool state);
1040 
1053 #define pLog(level, ...) _pLog(level, __FILE__, __func__, __LINE__, __VA_ARGS__);
1054 
1055 void _pLog(int, const char *, const char *, int, const char *, ...);
1056 
1057 #define logY(...) pLog(LOG_EMERGENCY, __VA_ARGS__)
1058 #define logA(...) pLog(LOG_ALERT, __VA_ARGS__)
1059 #define logC(...) pLog(LOG_CRITICAL, __VA_ARGS__)
1060 #define logE(...) pLog(LOG_ERROR, __VA_ARGS__)
1061 #define logW(...) pLog(LOG_WARNING, __VA_ARGS__)
1062 #define logN(...) pLog(LOG_NOTICE, __VA_ARGS__)
1063 #define logP(...) pLog(LOG_PASS, __VA_ARGS__)
1064 #define logI(...) pLog(LOG_INFO, __VA_ARGS__)
1065 #define logD(...) pLog(LOG_DEBUG, __VA_ARGS__)
1066 
1072 #define logSY(format, string) do {\
1073  char *libsheepyInternalString = string;\
1074  logY(format, libsheepyInternalString);\
1075  free(libsheepyInternalString);\
1076  } while(0)
1077 
1083 #define logSA(format, string) do {\
1084  char *libsheepyInternalString = string;\
1085  logA(format, libsheepyInternalString);\
1086  free(libsheepyInternalString);\
1087  } while(0)
1088 
1094 #define logSC(format, string) do {\
1095  char *libsheepyInternalString = string;\
1096  logC(format, libsheepyInternalString);\
1097  free(libsheepyInternalString);\
1098  } while(0)
1099 
1105 #define logSE(format, string) do {\
1106  char *libsheepyInternalString = string;\
1107  logE(format, libsheepyInternalString);\
1108  free(libsheepyInternalString);\
1109  } while(0)
1110 
1116 #define logSW(format, string) do {\
1117  char *libsheepyInternalString = string;\
1118  logW(format, libsheepyInternalString);\
1119  free(libsheepyInternalString);\
1120  } while(0)
1121 
1127 #define logSN(format, string) do {\
1128  char *libsheepyInternalString = string;\
1129  logN(format, libsheepyInternalString);\
1130  free(libsheepyInternalString);\
1131  } while(0)
1132 
1138 #define logSP(format, string) do {\
1139  char *libsheepyInternalString = string;\
1140  logP(format, libsheepyInternalString);\
1141  free(libsheepyInternalString);\
1142  } while(0)
1143 
1149 #define logSI(format, string) do {\
1150  char *libsheepyInternalString = string;\
1151  logI(format, libsheepyInternalString);\
1152  free(libsheepyInternalString);\
1153  } while(0)
1154 
1160 #define logSD(format, string) do {\
1161  char *libsheepyInternalString = string;\
1162  logD(format, libsheepyInternalString);\
1163  free(libsheepyInternalString);\
1164  } while(0)
1165 
1166 
1168 extern uint64_t logMask;
1169 
1200 #define pLogMask(mask, level, ...) if ((mask) & logMask) pLog(level, __VA_ARGS__)
1201 
1202 #define logMY(mask, ...) pLogMask(mask, LOG_EMERGENCY, __VA_ARGS__)
1203 #define logMA(mask, ...) pLogMask(mask, LOG_ALERT, __VA_ARGS__)
1204 #define logMC(mask, ...) pLogMask(mask, LOG_CRITICAL, __VA_ARGS__)
1205 #define logME(mask, ...) pLogMask(mask, LOG_ERROR, __VA_ARGS__)
1206 #define logMW(mask, ...) pLogMask(mask, LOG_WARNING, __VA_ARGS__)
1207 #define logMN(mask, ...) pLogMask(mask, LOG_NOTICE, __VA_ARGS__)
1208 #define logMP(mask, ...) pLogMask(mask, LOG_PASS, __VA_ARGS__)
1209 #define logMI(mask, ...) pLogMask(mask, LOG_INFO, __VA_ARGS__)
1210 #define logMD(mask, ...) pLogMask(mask, LOG_DEBUG, __VA_ARGS__)
1211 
1212 // show log messages in mask
1213 #define showLogsInMask(mask) logMask |= mask
1214 
1215 // hide log messages in mask
1216 #define hideLogsInMask(mask) logMask &= ~(mask)
1217 
1223 #define logSMY(mask, format, string) do {\
1224  char *libsheepyInternalString = string;\
1225  logMY(mask, format, libsheepyInternalString);\
1226  free(libsheepyInternalString);\
1227  } while(0)
1228 
1234 #define logSMA(mask, format, string) do {\
1235  char *libsheepyInternalString = string;\
1236  logMA(mask, format, libsheepyInternalString);\
1237  free(libsheepyInternalString);\
1238  } while(0)
1239 
1245 #define logSMC(mask, format, string) do {\
1246  char *libsheepyInternalString = string;\
1247  logMC(mask, format, libsheepyInternalString);\
1248  free(libsheepyInternalString);\
1249  } while(0)
1250 
1256 #define logSME(mask, format, string) do {\
1257  char *libsheepyInternalString = string;\
1258  logME(mask, format, libsheepyInternalString);\
1259  free(libsheepyInternalString);\
1260  } while(0)
1261 
1267 #define logSMW(mask, format, string) do {\
1268  char *libsheepyInternalString = string;\
1269  logMW(mask, format, libsheepyInternalString);\
1270  free(libsheepyInternalString);\
1271  } while(0)
1272 
1278 #define logSMN(mask, format, string) do {\
1279  char *libsheepyInternalString = string;\
1280  logMN(mask, format, libsheepyInternalString);\
1281  free(libsheepyInternalString);\
1282  } while(0)
1283 
1289 #define logSMP(mask, format, string) do {\
1290  char *libsheepyInternalString = string;\
1291  logMP(mask, format, libsheepyInternalString);\
1292  free(libsheepyInternalString);\
1293  } while(0)
1294 
1300 #define logSMI(mask, format, string) do {\
1301  char *libsheepyInternalString = string;\
1302  logMI(mask, format, libsheepyInternalString);\
1303  free(libsheepyInternalString);\
1304  } while(0)
1305 
1311 #define logSMD(mask, format, string) do {\
1312  char *libsheepyInternalString = string;\
1313  logMD(mask, format, libsheepyInternalString);\
1314  free(libsheepyInternalString);\
1315  } while(0)
1316 
1317 // QSORT
1318 
1319 /*
1320  * Copyright (c) 2013, 2017 Alexey Tourbin
1321  *
1322  * Permission is hereby granted, free of charge, to any person obtaining a copy
1323  * of this software and associated documentation files (the "Software"), to deal
1324  * in the Software without restriction, including without limitation the rights
1325  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1326  * copies of the Software, and to permit persons to whom the Software is
1327  * furnished to do so, subject to the following conditions:
1328  *
1329  * The above copyright notice and this permission notice shall be included in
1330  * all copies or substantial portions of the Software.
1331  *
1332  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1333  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1334  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1335  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1336  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1337  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1338  * SOFTWARE.
1339  */
1340 
1341 /*
1342  * https://github.com/svpv/qsort.git
1343  * commit 21f056356e901467b7362240dac70edeedfa2b89
1344  */
1345 
1346 /*
1347  * This is a traditional Quicksort implementation which mostly follows
1348  * [Sedgewick 1978]. Sorting is performed entirely on array indices,
1349  * while actual access to the array elements is abstracted out with the
1350  * user-defined `LESS` and `SWAP` primitives.
1351  *
1352  * Synopsis:
1353  * QSORT(N, LESS, SWAP);
1354  * where
1355  * N - the number of elements in A[];
1356  * LESS(i, j) - compares A[i] to A[j];
1357  * SWAP(i, j) - exchanges A[i] with A[j].
1358  *
1359  * Examples:
1360  * - int array:
1361  * int A[] = {3,2,1};
1362  * int tmp;
1363  *
1364  * #define LESS(i, j) A[i] < A[j]
1365  * #define SWAP(i, j) tmp = A[i], A[i] = A[j], A[j] = tmp
1366  *
1367  * QSORT(3, LESS, SWAP);
1368  * #undef LESS
1369  * #undef SWAP
1370  *
1371  *
1372  * - string array/list:
1373  * char **strs = listCreateS("fsd", "sdf", "ffds","asd");
1374  * char *tmp;
1375  *
1376  * #define LESS(i,j) (strcmp(strs[i], strs[j]) < 0)
1377  * #define SWAP(i,j) tmp = strs[i], strs[i] = strs[j], strs[j] = tmp
1378  *
1379  * QSORT(listLengthS(strs), LESS, SWAP);
1380  * #undef LESS
1381  * #undef SWAP
1382  *
1383  */
1384 
1385 /* Sort 3 elements. */
1386 #define Q_SORT3(q_a1, q_a2, q_a3, Q_LESS, Q_SWAP) do {\
1387  if (Q_LESS(q_a2, q_a1)) {\
1388  if (Q_LESS(q_a3, q_a2))\
1389  Q_SWAP(q_a1, q_a3);\
1390  else {\
1391  Q_SWAP(q_a1, q_a2);\
1392  if (Q_LESS(q_a3, q_a2))\
1393  Q_SWAP(q_a2, q_a3);\
1394  }\
1395  }\
1396  else if (Q_LESS(q_a3, q_a2)) {\
1397  Q_SWAP(q_a2, q_a3);\
1398  if (Q_LESS(q_a2, q_a1))\
1399  Q_SWAP(q_a1, q_a2); \
1400  }\
1401  } while (0)
1402 
1403 /* Partition [q_l,q_r] around a pivot. After partitioning,
1404  * [q_l,q_j] are the elements that are less than or equal to the pivot,
1405  * while [q_i,q_r] are the elements greater than or equal to the pivot. */
1406 #define Q_PARTITION(q_l, q_r, q_i, q_j, Q_UINT, Q_LESS, Q_SWAP) do {\
1407  /* The middle element, not to be confused with the median. */\
1408  Q_UINT UNIQVAR(q_m) = q_l + ((q_r - q_l) >> 1);\
1409  /* Reorder the second, the middle, and the last items.\
1410  * As [Edelkamp Weiss 2016] explain, using the second element\
1411  * instead of the first one helps avoid bad behaviour for\
1412  * decreasingly sorted arrays. This method is used in recent\
1413  * versions of gcc's std::sort, see gcc bug 58437#c13, although\
1414  * the details are somewhat different (cf. #c14). */\
1415  Q_SORT3(q_l + 1, UNIQVAR(q_m), q_r, Q_LESS, Q_SWAP);\
1416  /* Place the median at the beginning. */\
1417  Q_SWAP(q_l, UNIQVAR(q_m));\
1418  /* Partition [q_l+2, q_r-1] around the median which is in q_l.\
1419  * q_i and q_j are initially off by one, they get decremented\
1420  * in the do-while loops. */\
1421  q_i = q_l + 1; q_j = q_r;\
1422  while (1) {\
1423  do q_i++; while (Q_LESS(q_i, q_l));\
1424  do q_j--; while (Q_LESS(q_l, q_j));\
1425  if (q_i >= q_j) break; /* Sedgewick says "until j < i" */\
1426  Q_SWAP(q_i, q_j);\
1427  }\
1428  /* Compensate for the i==j case. */\
1429  q_i = q_j + 1;\
1430  /* Put the median to its final place. */\
1431  Q_SWAP(q_l, q_j);\
1432  /* The median is not part of the left subfile. */\
1433  q_j--;\
1434  } while (0)
1435 
1436 /* Insertion sort is applied to small subfiles - this is contrary to
1437  * Sedgewick's suggestion to run a separate insertion sort pass after
1438  * the partitioning is done. The reason I don't like a separate pass
1439  * is that it triggers extra comparisons, because it can't see that the
1440  * medians are already in their final positions and need not be rechecked.
1441  * Since I do not assume that comparisons are cheap, I also do not try
1442  * to eliminate the (q_j > q_l) boundary check. */
1443 #define Q_INSERTION_SORT(q_l, q_r, Q_UINT, Q_LESS, Q_SWAP) do {\
1444  Q_UINT UNIQVAR(q_i), UNIQVAR(q_j);\
1445  /* For each item starting with the second... */\
1446  for (UNIQVAR(q_i) = q_l + 1; UNIQVAR(q_i) <= q_r; UNIQVAR(q_i)++)\
1447  /* move it down the array so that the first part is sorted. */\
1448  for (UNIQVAR(q_j) = UNIQVAR(q_i); UNIQVAR(q_j) > q_l && (Q_LESS(UNIQVAR(q_j), UNIQVAR(q_j) - 1)); UNIQVAR(q_j)--)\
1449  Q_SWAP(UNIQVAR(q_j), UNIQVAR(q_j) - 1);\
1450  } while (0)
1451 
1452 /* When the size of [q_l,q_r], i.e. q_r-q_l+1, is greater than or equal to
1453  * Q_THRESH, the algorithm performs recursive partitioning. When the size
1454  * drops below Q_THRESH, the algorithm switches to insertion sort.
1455  * The minimum valid value is probably 5 (with 5 items, the second and
1456  * the middle items, the middle itself being rounded down, are distinct). */
1457 #define Q_THRESH 16
1458 
1459 /* The main loop. */
1460 #define Q_LOOP(Q_UINT, Q_N, Q_LESS, Q_SWAP) do {\
1461  Q_UINT UNIQVAR(q_l) = 0;\
1462  Q_UINT UNIQVAR(q_r) = (Q_N) - 1;\
1463  Q_UINT UNIQVAR(q_sp) = 0; /* the number of frames pushed to the stack */\
1464  struct { Q_UINT q_l, q_r; }\
1465  /* On 32-bit platforms, to sort a "char[3GB+]" array,\
1466  * it may take full 32 stack frames. On 64-bit CPUs,\
1467  * though, the address space is limited to 48 bits.\
1468  * The usage is further reduced if Q_N has a 32-bit type. */\
1469  UNIQVAR(q_st)[sizeof(Q_UINT) > 4 && sizeof(Q_N) > 4 ? 48 : 32];\
1470  while (1) {\
1471  if (UNIQVAR(q_r) - UNIQVAR(q_l) + 1 >= Q_THRESH) {\
1472  Q_UINT UNIQVAR(q_i), UNIQVAR(q_j);\
1473  Q_PARTITION(UNIQVAR(q_l), UNIQVAR(q_r), UNIQVAR(q_i), UNIQVAR(q_j), Q_UINT, Q_LESS, Q_SWAP);\
1474  /* Now have two subfiles: [q_l,q_j] and [q_i,q_r].\
1475  * Dealing with them depends on which one is bigger. */\
1476  if (UNIQVAR(q_j) - UNIQVAR(q_l) >= UNIQVAR(q_r) - UNIQVAR(q_i))\
1477  Q_SUBFILES(UNIQVAR(q_l), UNIQVAR(q_j), UNIQVAR(q_i), UNIQVAR(q_r));\
1478  else\
1479  Q_SUBFILES(UNIQVAR(q_i), UNIQVAR(q_r), UNIQVAR(q_l), UNIQVAR(q_j));\
1480  }\
1481  else {\
1482  Q_INSERTION_SORT(UNIQVAR(q_l), UNIQVAR(q_r), Q_UINT, Q_LESS, Q_SWAP);\
1483  /* Pop subfiles from the stack, until it gets empty. */\
1484  if (UNIQVAR(q_sp) == 0) break;\
1485  UNIQVAR(q_sp)--;\
1486  UNIQVAR(q_l) = UNIQVAR(q_st)[UNIQVAR(q_sp)].q_l;\
1487  UNIQVAR(q_r) = UNIQVAR(q_st)[UNIQVAR(q_sp)].q_r;\
1488  }\
1489  }\
1490  } while (0)
1491 
1492 /* The missing part: dealing with subfiles.
1493  * Assumes that the first subfile is not smaller than the second. */
1494 #define Q_SUBFILES(q_l1, q_r1, q_l2, q_r2) do {\
1495  /* If the second subfile is only a single element, it needs\
1496  * no further processing. The first subfile will be processed\
1497  * on the next iteration (both subfiles cannot be only a single\
1498  * element, due to Q_THRESH). */\
1499  if (q_l2 == q_r2) {\
1500  UNIQVAR(q_l) = q_l1;\
1501  UNIQVAR(q_r) = q_r1;\
1502  }\
1503  else {\
1504  /* Otherwise, both subfiles need processing.\
1505  * Push the larger subfile onto the stack. */\
1506  UNIQVAR(q_st)[UNIQVAR(q_sp)].q_l = q_l1;\
1507  UNIQVAR(q_st)[UNIQVAR(q_sp)].q_r = q_r1;\
1508  UNIQVAR(q_sp)++;\
1509  /* Process the smaller subfile on the next iteration. */\
1510  UNIQVAR(q_l) = q_l2;\
1511  UNIQVAR(q_r) = q_r2;\
1512  }\
1513  } while (0)
1514 
1515 /* And now, ladies and gentlemen, may I proudly present to you... */
1516 #define QSORT(Q_N, Q_LESS, Q_SWAP) do {\
1517  if ((Q_N) > 1) {\
1518  if (sizeof(Q_N) == sizeof(unsigned long)) {\
1519  Q_LOOP(unsigned long, Q_N, Q_LESS, Q_SWAP);}\
1520  else if (sizeof(Q_N) <= sizeof(unsigned)) {\
1521  Q_LOOP(unsigned, Q_N, Q_LESS, Q_SWAP);}\
1522  }\
1523  } while (0)
1524 
1525 // QSORT END
1526 
1527 // BINARY SEARCH
1528 
1555 #define BSEARCH(RESULT_INDEX, SEARCH_ELEMENT, B_N, B_LESS, B_EQUAL) do {\
1556  ssize_t UNIQVAR(b_first) = 0, UNIQVAR(b_middle), UNIQVAR(b_last);\
1557  UNIQVAR(b_last) = B_N-1;\
1558  while (UNIQVAR(b_first) <= UNIQVAR(b_last)) {\
1559  UNIQVAR(b_middle) = (UNIQVAR(b_first)+UNIQVAR(b_last))/2;\
1560  if (B_LESS(UNIQVAR(b_middle), SEARCH_ELEMENT)) UNIQVAR(b_first) = UNIQVAR(b_middle) + 1;\
1561  else if (B_EQUAL(UNIQVAR(b_middle), SEARCH_ELEMENT)) {\
1562  RESULT_INDEX = UNIQVAR(b_middle);\
1563  goto UNIQVAR(end);\
1564  }\
1565  else UNIQVAR(b_last) = UNIQVAR(b_middle) -1;\
1566  }\
1567  /* element not found */\
1568  RESULT_INDEX = -1;\
1569  UNIQVAR(end):;\
1570  } while(0)
1571 
1572 // BINARY SEARCH END
1573 
1574 // makeRoom is dynamic memory allocation algorithm
1575 // given a length, an allocated size and the additionnal length,
1576 // makeRoom returns the new allocated size for realloc
1577 // when the new allocated size equals alloc value, there is no need to realloc the memory, enough space is already available
1578 #define libsheepyPrealloc (1024*1024)
1579 #define makeRoom(length, alloc, addlength) funcbegin\
1580  typeof(alloc) r;\
1581  typeof(alloc) newlen = (length) + (addlength);\
1582  if (newlen < (alloc)) {\
1583  r = alloc;\
1584  } \
1585  else {\
1586  if (newlen < libsheepyPrealloc) {\
1587  r = newlen * 2;\
1588  }\
1589  else {\
1590  r = newlen + libsheepyPrealloc;\
1591  }\
1592  }\
1593  r;\
1594  funcend
1595 
1596 // initialize libsheepy (optional, for debug)
1597 typedef void(*initLibsheepyObjectP)(void);
1598 void initLibsheepyF(const char *progPath, initLibsheepyObjectP initF);
1599 #define initLibsheepy(progPath) initLibsheepyF(progPath, NULL)
1600 
1601 // free internal buffers at exit
1602 void finalizeLibsheepyCharAtExit(void);
1603 
1604 // get current stack limit - returns 0 when error
1605 int64_t getStackLimit(void) MUST_CHECK;
1606 
1607 // set stack limit (-1 for unlimited) - returns 0 when error
1608 int setStackLimit(int64_t stackSize) MUST_CHECK;
1609 
1610 // enable core dump
1611 int enableCoreDump(void) MUST_CHECK;
1612 
1613 // get program name
1614 const char *getProgName(void) MUST_CHECK;
1615 
1616 // set program name
1617 bool setProgName(const char *name) MUST_CHECK;
1618 
1619 // set default program name
1620 void setDefaultProgName(void);
1621 
1622 // free ProgName
1623 void freeProgName(void);
1624 
1625 // get program path as given in the shell
1626 const char *getProgPath(void) MUST_CHECK;
1627 
1628 // get real program path, allocates path string internally
1629 const char *getRealProgPath(void) MUST_CHECK;
1630 
1631 // free real program path
1632 void freeRealProgPath(void);
1633 
1634 // run system command and free command buffer
1635 #define systemNFree(command) systemNFreeF(command, __LINE__, __func__, __FILE__)
1636 int systemNFreeF(char *command, int line, const char *thisFunc, const char *thisFileName) MUST_CHECK;
1637 
1638 // get modification time for path
1639 time_t getModificationTime(const char *path) MUST_CHECK;
1640 
1641 // set modification time for path
1642 int setModificationTime(const char *path, time_t mtime) MUST_CHECK;
1643 
1644 // true when path is readable
1645 bool isReadable(const char *path) MUST_CHECK;
1646 
1647 // true when path is writable
1648 bool isWritable(const char *path) MUST_CHECK;
1649 
1650 // true when path is executable
1651 bool isExecutable(const char *path) MUST_CHECK;
1652 
1653 // compare modification times for path1 and path2
1654 bool equalModificationTimes(const char *path1, const char *path2) MUST_CHECK;
1655 
1656 // get current unix time
1657 time_t getCurrentUnixTime(void) MUST_CHECK;
1658 
1659 // convert date string to unix time
1660 time_t strToUnixTime(const char *date, const char *format) MUST_CHECK;
1661 
1662 // convert unix time to string
1663 char *timeToS(const time_t t) MUST_CHECK;
1664 char *bTimeToS(char *dst, const time_t t) MUST_CHECK;
1665 char *bLTimeToS(char *dst, size_t dstSize, const time_t t) MUST_CHECK;
1666 
1667 // convert unix time to Y-m-d H:M:S string
1668 char *timeToYMDS(const time_t t) MUST_CHECK;
1669 char *bTimeToYMDS(char *dst, const time_t t) MUST_CHECK;
1670 char *bLTimeToYMDS(char *dst, size_t dstSize, const time_t t) MUST_CHECK;
1671 
1672 // get current date in ctime format
1673 char *getCurrentDate(void) MUST_CHECK;
1674 char *bGetCurrentDate(char *dst) MUST_CHECK;
1675 char *bLGetCurrentDate(char *dst, size_t dstSize) MUST_CHECK;
1676 
1677 // get current date in Y-m-d H:M:S format
1678 char *getCurrentDateYMD(void) MUST_CHECK;
1679 char *bGetCurrentDateYMD(char *dst) MUST_CHECK;
1680 char *bLGetCurrentDateYMD(char *dst, size_t dstSize) MUST_CHECK;
1681 
1682 // dirname
1683 char *shDirname(const char *path) MUST_CHECK;
1684 char *bDirname(char *path) MUST_CHECK;
1685 char *bLDirname(char *path, size_t pathSize) MUST_CHECK;
1686 
1687 // expand home ~/
1688 char *expandHome(const char *path) MUST_CHECK;
1689 char *iExpandHome(char **path) MUST_CHECK;
1690 char *bExpandHome(char *path) MUST_CHECK;
1691 char *bLExpandHome(char *path, size_t pathSize) MUST_CHECK;
1692 
1693 // normalize path
1694 char *normalizePath(const char *path) MUST_CHECK;
1695 char *iNormalizePath(char **path) MUST_CHECK;
1696 char *bNormalizePath(char *path) MUST_CHECK;
1697 char *bLNormalizePath(char *path, size_t pathSize) MUST_CHECK;
1698 
1699 // relative path
1700 char *relPath(const char *path, const char *start) MUST_CHECK;
1701 char *iRelPath(char **path, const char *start) MUST_CHECK;
1702 char *bRelPath(char *dest, const char *path, const char *start) MUST_CHECK;
1703 char *bLRelPath(char *dest, size_t destSize, char *path, const char *start) MUST_CHECK;
1704 
1705 // get home path
1706 char *getHomePath(void) MUST_CHECK;
1707 char *bGetHomePath(char *path) MUST_CHECK;
1708 char *bLGetHomePath(char *path, size_t pathSize) MUST_CHECK;
1709 const char *getCHomePath(void) MUST_CHECK;
1710 
1711 // get current working directory
1712 char *getCwd(void) MUST_CHECK;
1713 char *bLGetCwd(char *path, size_t pathSize) MUST_CHECK;
1714 
1715 // change directory
1716 int chDir(const char *path) MUST_CHECK;
1717 
1718 // true when path is directory
1719 bool isDir(const char *path) MUST_CHECK;
1720 
1721 // read link to a new string
1722 char *shReadlink(const char *path) MUST_CHECK;
1723 
1724 // read link chain to the end to a new string
1725 char *endlink(const char *path) MUST_CHECK;
1726 
1727 // true when path is symbolic link
1728 bool isLink(const char *path) MUST_CHECK;
1729 
1730 // file and dir exists
1731 bool fileExists(const char *filePath) MUST_CHECK;
1732 #define isPath fileExists
1733 
1734 // chmod "721"
1735 bool fileChmod(const char *filePath, mode_t mode) MUST_CHECK;
1736 
1737 // file size
1738 ssize_t fileSize(const char *filePath) MUST_CHECK;
1739 ssize_t fileSizeFP(FILE *fp) MUST_CHECK;
1740 
1741 // read file
1742 void *readFileToS(const char *filePath) MUST_CHECK;
1743 void *bReadFileToS(const char *filePath, void *dst) MUST_CHECK;
1744 void *bLReadFileToS(const char *filePath, void *dst, size_t dstSize) MUST_CHECK;
1745 ssize_t readFile(const char *filePath, void **buffer) MUST_CHECK;
1746 ssize_t bReadFile(const char *filePath, void *buffer) MUST_CHECK;
1747 ssize_t bLReadFile(const char *filePath, void *buffer, size_t dstSize) MUST_CHECK;
1748 void *readStreamToS(FILE *fp) MUST_CHECK;
1749 void *bReadStreamToS(FILE *fp, void *dst) MUST_CHECK;
1750 void *bLReadStreamToS(FILE *fp, void *dst, size_t dstSize) MUST_CHECK;
1751 // defines without '...ToS'
1752 #define readFileS readFileToS
1753 #define bReadFileS bReadFileToS
1754 #define bLReadFileS bLReadFileToS
1755 #define readStreamS readStreamToS
1756 #define bReadStreamS bReadStreamToS
1757 #define bLReadStreamS bLReadStreamToS
1758 
1759 // write file
1760 int writeFileS(const char *filePath, const char *string) MUST_CHECK;
1761 int writeFile(const char *filePath, void *buffer, size_t len) MUST_CHECK;
1762 int writeStreamS(FILE *fp, const char *string) MUST_CHECK;
1763 int writeLStream(FILE *fp, void *buffer, size_t len) MUST_CHECK;
1764 
1765 // append string to file
1766 bool appendFileS(const char *filePath, const char *string) MUST_CHECK;
1767 bool appendFile(const char *filePath, void *buffer, size_t len) MUST_CHECK;
1768 
1769 // walkDir lists files only
1770 char **walkDir(const char* dirPath) MUST_CHECK;
1771 
1772 // walkDirDir lists directories
1773 char **walkDirDir(const char* dirPath) MUST_CHECK;
1774 
1775 // readDir lists files in a directory
1776 char **readDir(const char *dirPath) MUST_CHECK;
1777 
1778 // readDirDir lists directories in a directory
1779 char **readDirDir(const char *dirPath) MUST_CHECK;
1780 
1781 // walkDirAll lists files and directories
1782 char **walkDirAll(const char* dirPath) MUST_CHECK;
1783 
1784 // readDirAll lists files and directories in a directory
1785 char **readDirAll(const char *dirPath) MUST_CHECK;
1786 
1787 // get umask
1788 mode_t getUmask(void) MUST_CHECK;
1789 
1790 // get current permissions for creating directories
1791 mode_t getCurrentPermissions(void) MUST_CHECK;
1792 
1793 // recursive mkdir
1794 int mkdirParents(const char* path) MUST_CHECK;
1795 
1796 // delete files and directories
1797 int rmAll(const char* path) MUST_CHECK;
1798 
1799 // copy files recursively
1800 int copy(const char* src, const char* dst) MUST_CHECK;
1801 
1802 // rename file
1803 int shRename(const char* src, const char* dst) MUST_CHECK;
1804 
1805 // move files recursively
1806 int shMove(const char* src, const char* dst) MUST_CHECK;
1807 
1808 // use /dev/urandom as a source of random numbers
1809 void setSoftwareRandom(void);
1810 
1811 // use cpu random instruction as a source of random numbers
1812 void setHardwareRandom(void);
1813 
1814 // open /dev/urandom in libsheepy
1815 int randomUrandomOpen(void) MUST_CHECK;
1816 
1817 // close /dev/urandom in libsheepy
1818 void randomUrandomClose(void);
1819 
1820 // return random 64 bit unsigned integer
1821 uint64_t randomWord(void) MUST_CHECK;
1822 
1823 // return random 64 bit unsigned integer from the cpu
1824 uint64_t randomWordFromHW(void) MUST_CHECK;
1825 
1826 // return a random value between 0 and range 0<=value<range
1827 uint64_t randomChoice(uint64_t range) MUST_CHECK;
1828 
1829 // generate random string
1830 char *randomS(uint64_t length) MUST_CHECK;
1831 char *bRandomS(char *dst, size_t length) MUST_CHECK;
1832 
1833 // generate random alpha numerical string
1834 char *randomAlphaNumS(uint64_t length) MUST_CHECK;
1835 char *bRandomAlphaNumS(char *dst, size_t dstSize) MUST_CHECK;
1836 
1837 // read user input (one line) as a string
1838 char *readS(void) MUST_CHECK;
1839 char *bLReadS(char *dst, size_t dstSize) MUST_CHECK;
1840 
1841 // read hidden password as a string - like getpass
1842 char *readPasswordS(void) MUST_CHECK;
1843 
1844 // write zero to all bytes in string with memset, for clearing password buffers
1845 bool zeroS(char *string) MUST_CHECK;
1846 
1847 // write zero to all bytes in buffer with memset
1848 bool zeroBuf(void *buf, size_t len) MUST_CHECK;
1849 
1850 // allocate and copy buffer
1851 void *memdup(const void *buf, size_t size) MUST_CHECK;
1852 
1853 // wait until press the enter key
1854 void readEnter(void);
1855 
1856 // TODO writeLine - copy cg_c code
1857 
1858 // readLine
1859 char *readLine(FILE *fp) MUST_CHECK;
1860 
1861 // convert char to string by declaring string dst with c in it
1862 #define charToS(dst, c) \
1863  ;char dst[2] = {c, 0}
1864 
1865 // free many char*
1866 void freeManySF(char *paramType, ...);
1867 #define freeManyS(...) freeManySF("", __VA_ARGS__, NULL)
1868 
1869 // duplicate string
1870 char *dupS(const char *string) MUST_CHECK;
1871 
1872 // print like printf, the formating can be NULL
1873 void shPrintfS(const char *fmt, ...);
1874 
1875 // stderr printf, the formating can be NULL
1876 void shEPrintfS(const char *fmt, ...);
1877 
1878 // print and free s
1879 void logNFree(char *s);
1880 
1881 // print buf as hexadecimal
1882 void loghex(const void *buf, size_t len);
1883 
1884 // create a string with bytes in buf converted to hex strings: 0xff,
1885 char *toHexS(const void *buf, size_t len) MUST_CHECK;
1886 
1887 // create a string with bytes in buf converted to hex strings separated by separator: 0xffSEP
1888 char *toHexSepS(const void *buf, size_t len, const char *separator) MUST_CHECK;
1889 
1890 // create a string with bytes in buf converted to hex strings separated by separator and with head string in front of earch byte: HEADffSEP
1891 char *toHexHeadSepS(const void *buf, size_t len, const char *head, const char *separator) MUST_CHECK;
1892 
1893 // print new line
1894 #define put puts("");
1895 
1896 // copy src to dst
1897 char *strCpy(char *restrict dst, const char *restrict src) MUST_CHECK;
1898 // copy string to buffer given string length: strNCpy(buffer, string, lenS(string));
1899 // null safe version of strncpy
1900 char *strNCpy(char *restrict dst, const char *restrict src, size_t srcSize) MUST_CHECK;
1901 char *strLCpy(char *restrict dst, size_t dstSize, const char *restrict src) MUST_CHECK;
1902 
1903 // concatenate src to dst
1904 char *strCat(char *restrict dst, const char *restrict src) MUST_CHECK;
1905 char *strNCat(char *restrict dst, const char *restrict src, size_t srcLen) MUST_CHECK;
1906 char *strLCat(char *restrict dst, size_t dstSize, const char *restrict src) MUST_CHECK;
1907 char *strLNCat(char *restrict dst, size_t dstSize, const char *restrict src, size_t srcLen) MUST_CHECK;
1908 
1909 // cat: f("qwd ", str," werr ", str2)
1910 char *catSF(const char *paramType, ...) MUST_CHECK;
1911 #define catS(...) catSF("", __VA_ARGS__, NULL)
1912 
1913 // cat and copy result to dst buffer
1914 char *iCatSF(char *dst, const char *paramType, ...) MUST_CHECK;
1915 #define iCatS(dst, ...) iCatSF(dst, "", __VA_ARGS__, NULL)
1916 #define bCatS iCatS
1917 char *bLCatSF(char *dst, size_t dstSize, const char *paramType, ...) MUST_CHECK;
1918 #define bLCatS(dst, dstSize, ...) bLCatSF(dst, dstSize, "", __VA_ARGS__, NULL)
1919 
1920 // allocate and format string using asprintf
1921 char *formatS(const char *fmt, ...) MUST_CHECK;
1922 
1924 char *bFormatS(char *string, const char *fmt, ...) MUST_CHECK;
1925 
1927 char *bLFormatS(char *string, size_t stringSize, const char *fmt, ...) MUST_CHECK;
1928 
1929 // append strings
1930 char *appendS(const char *string1, const char *string2) MUST_CHECK;
1931 char *appendCharS(const char *string1, char c) MUST_CHECK;
1932 char *appendSChar(char c, const char *string2) MUST_CHECK;
1933 char *iAppendS(char **string1, const char *string2) MUST_CHECK;
1934 char *iAppendCharS(char **string1, char c) MUST_CHECK;
1935 char *iAppendNFreeS(char **string1, char *string2) MUST_CHECK;
1936 char *iAppendManySF(char **string, const char *paramType, ...) MUST_CHECK;
1937 #define iAppendManyS(s, s1, ...) iAppendManySF(s, s1, __VA_ARGS__, NULL)
1938 char *bAppendManySF(char *string, const char *paramType, ...) MUST_CHECK;
1939 #define bAppendManyS(s, s1, ...) bAppendManySF(s, s1, __VA_ARGS__, NULL)
1940 char *bLAppendManySF(char *string, size_t stringSize, const char *paramType, ...) MUST_CHECK;
1941 #define bLAppendManyS(s, sSize, s1, ...) bLAppendManySF(s, sSize, s1, __VA_ARGS__, NULL)
1942 
1943 // prepend string
1944 char *prependS(const char *string1, const char *string2) MUST_CHECK;
1945 char *prependCharS(const char *string1, char c) MUST_CHECK;
1946 char *prependSChar(char c, const char *string2) MUST_CHECK;
1947 char *iPrependS(char **string1, const char *string2) MUST_CHECK;
1948 char *iPrependCharS(char **string1, char c) MUST_CHECK;
1949 char *iPrependNFreeS(char **string1, char *string2) MUST_CHECK;
1950 char *bPrependS(char *string1, const char *string2) MUST_CHECK;
1951 char *bLPrependS(char *string1, size_t string1Size, const char *string2) MUST_CHECK;
1952 
1953 // string replace
1954 char *replaceS(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
1955 char *replaceCharSS(const char *s, char olds, const char *news, size_t max) MUST_CHECK;
1956 char *replaceSCharS(const char *s, const char *olds, char news, size_t max) MUST_CHECK;
1957 char *replaceCharCharS(const char *s, char olds, char news, size_t max) MUST_CHECK;
1958 #define replaceS_max(s,olds,news) replaceS(s,olds,news, 0)
1959 #define replaceSMax replaceS_max
1960 // TODO add support for all types, create a generic, create ignore case version
1961 size_t replaceSLen(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
1962 #define replaceSMaxLen(s,olds,news) replaceSLen(s,olds,news, 0)
1963 char* iReplaceS(char **s, const char *olds, const char *news, size_t max) MUST_CHECK;
1964 char* iReplaceCharSS(char **s, char olds, const char *news, size_t max) MUST_CHECK;
1965 char* iReplaceSCharS(char **s, const char *olds, char news, size_t max) MUST_CHECK;
1966 char* iReplaceCharCharS(char **s, char olds, char news, size_t max) MUST_CHECK;
1967 #define iReplaceS_max(s,olds,news) iReplaceS(s,olds,news, 0)
1968 #define iReplaceSMax iReplaceS_max
1969 char* bReplaceS(char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
1970 #define bReplaceS_max(s,olds,news) bReplaceS(s,olds,news, 0)
1971 #define bReplaceSMax bReplaceS_max
1972 char* bLReplaceS(char *s, size_t sSize, const char *olds, const char *news, size_t max) MUST_CHECK;
1973 #define bLReplaceS_max(s,sSize,olds,news) bLReplaceS(s,sSize,olds,news, 0)
1974 #define bLReplaceSMax bLReplaceS_max
1975 
1976 // string replace many olds with news (s, olds1, news1, olds2, news2,...)
1977 char *replaceManySF(const char *paramType, ...) MUST_CHECK;
1978 #define replaceManyS(s, ...) replaceManySF(s, __VA_ARGS__, NULL)
1979 char *iReplaceManySF(char **string, char *paramType, ...) MUST_CHECK;
1980 #define iReplaceManyS(s, olds, ...) iReplaceManySF(s, olds, __VA_ARGS__, NULL)
1981 char *bReplaceManySF(char *s, char *paramType, ...) MUST_CHECK;
1982 #define bReplaceManyS(s, olds, ...) bReplaceManySF(s, olds, __VA_ARGS__, NULL)
1983 char *bLReplaceManySF(char *s, size_t sSize, char *paramType, ...) MUST_CHECK;
1984 #define bLReplaceManyS(s, sSize, olds, ...) bLReplaceManySF(s, sSize, olds, __VA_ARGS__, NULL)
1985 
1986 // ignore case string replace
1987 char *icReplaceS(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
1988 char *icReplaceCharSS(const char *s, char olds, const char *news, size_t max) MUST_CHECK;
1989 char *icReplaceSCharS(const char *s, const char *olds, char news, size_t max) MUST_CHECK;
1990 char *icReplaceCharCharS(const char *s, char olds, char news, size_t max) MUST_CHECK;
1991 #define icReplaceS_max(s,olds,news) icReplaceS(s,olds,news, 0)
1992 #define icReplaceSMax icReplaceS_max
1993 char* iicReplaceS(char **s, const char *olds, const char *news, size_t max) MUST_CHECK;
1994 char* iicReplaceCharSS(char **s, char olds, const char *news, size_t max) MUST_CHECK;
1995 char* iicReplaceSCharS(char **s, const char *olds, char news, size_t max) MUST_CHECK;
1996 char* iicReplaceCharCharS(char **s, char olds, char news, size_t max) MUST_CHECK;
1997 #define iicReplaceS_max(s,olds,news) iicReplaceS(s,olds,news, 0)
1998 #define iicReplaceSMax iicReplaceS_max
1999 char* bicReplaceS(char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
2000 #define bicReplaceS_max(s,olds,news) bicReplaceS(s,olds,news, 0)
2001 #define bicReplaceSMax bicReplaceS_max
2002 char* bLicReplaceS(char *s, size_t sSize, const char *olds, const char *news, size_t max) MUST_CHECK;
2003 #define bLicReplaceS_max(s,sSize,olds,news) bLicReplaceS(s,sSize,olds,news, 0)
2004 #define bLicReplaceSMax bLicReplaceS_max
2005 
2006 // string replace many olds with news (s, olds1, news1, olds2, news2,...)
2007 char *icReplaceManySF(const char *paramType, ...) MUST_CHECK;
2008 #define icReplaceManyS(s, ...) icReplaceManySF(s, __VA_ARGS__, NULL)
2009 char *iicReplaceManySF(char **string, char *paramType, ...) MUST_CHECK;
2010 #define iicReplaceManyS(s, olds, ...) iicReplaceManySF(s, olds, __VA_ARGS__, NULL)
2011 char *bicReplaceManySF(char *s, char *paramType, ...) MUST_CHECK;
2012 #define bicReplaceManyS(s, olds, ...) bicReplaceManySF(s, olds, __VA_ARGS__, NULL)
2013 char *bLicReplaceManySF(char *s, size_t sSize, char *paramType, ...) MUST_CHECK;
2014 #define bLicReplaceManyS(s, sSize, olds, ...) bLicReplaceManySF(s, sSize, olds, __VA_ARGS__, NULL)
2015 
2016 // string equal (compare content)
2017 bool eqS(const char *string1, const char *string2) MUST_CHECK;
2018 #define strEq eqS
2019 bool eqCharS(char c, const char *string2) MUST_CHECK;
2020 bool eqSChar(const char *string1, char c) MUST_CHECK;
2021 
2022 // string equal at index (compare content)
2023 bool eqIS(const char *string1, const char *string2, int64_t index) MUST_CHECK;
2024 #define strIEq eqIS
2025 bool eqICharS(const char *string1, char c, int64_t index) MUST_CHECK;
2026 
2027 // look for string2 at string1 start
2028 bool startsWithS(const char *string1, const char *string2) MUST_CHECK;
2029 bool startsWithCharS(const char *string1, char c) MUST_CHECK;
2030 
2031 // look for string2 at string1 end
2032 bool endsWithS(const char *string1, const char *string2) MUST_CHECK;
2033 bool endsWithCharS(const char *string1, char c) MUST_CHECK;
2034 
2035 // count number of (non-overlapping) occurrences of a substring
2036 ssize_t countS(const char *s, const char *needle) MUST_CHECK;
2037 ssize_t countCharS(const char *s, char c) MUST_CHECK;
2038 
2039 // ignore case string equal (compare content)
2040 bool icEqS(const char *string1, const char *string2) MUST_CHECK;
2041 bool icEqCharS(char c, const char *string2) MUST_CHECK;
2042 bool icEqSChar(const char *string1, char c) MUST_CHECK;
2043 
2044 // ignore case string equal at index (compare content)
2045 bool icEqIS(const char *string1, const char *string2, int64_t index) MUST_CHECK;
2046 bool icEqICharS(const char *string1, char c, int64_t index) MUST_CHECK;
2047 
2048 // ignore case and look for string2 at string1 start
2049 bool icStartsWithS(const char *string1, const char *string2) MUST_CHECK;
2050 bool icStartsWithCharS(const char *string1, char c) MUST_CHECK;
2051 
2052 // ignore case look for string2 at string1 end
2053 bool icEndsWithS(const char *string1, const char *string2) MUST_CHECK;
2054 bool icEndsWithCharS(const char *string1, char c) MUST_CHECK;
2055 
2056 // ignore case and count number of (non-overlapping) occurrences of a substring
2057 ssize_t icCountS(const char *s, const char *needle) MUST_CHECK;
2058 ssize_t icCountCharS(const char *s, char c) MUST_CHECK;
2059 
2060 // has terminal control char (for example colors)
2061 bool hasCtrlChar(const char *string) MUST_CHECK;
2062 
2063 // remove terminal control char from string
2064 char *stripCtrlS(const char *string) MUST_CHECK;
2065 char *iStripCtrlS(char **string) MUST_CHECK;
2066 char *bStripCtrlS(char *string) MUST_CHECK;
2067 
2068 // remove ansi colors from string
2069 char *stripColorsS(const char *string) MUST_CHECK;
2070 char *iStripColorsS(char **string) MUST_CHECK;
2071 char *bStripColorsS(char *string) MUST_CHECK;
2072 
2073 // escape quotes and backslashes in string
2074 char* quoteS(const char *s, char delim) MUST_CHECK;
2075 char* bQuoteS(char *dest, const char *s, char delim) MUST_CHECK;
2076 char* bLQuoteS(char *dest, size_t destSize, const char *s, char delim) MUST_CHECK;
2077 size_t quoteLenS(const char *s, char delim) MUST_CHECK;
2078 // escape string to become a parsable json string
2079 char* escapeS(const char *s, char delim /*string delimiter ' or "*/) MUST_CHECK;
2080 char* bEscapeS(char *dest, const char *s, char delim /*string delimiter ' or "*/) MUST_CHECK;
2081 char* bLEscapeS(char *dest, size_t destSize, const char *s, char delim /*string delimiter ' or "*/) MUST_CHECK;
2082 size_t escapeLenS(const char *s, char delim /*string delimiter ' or "*/) MUST_CHECK;
2083 // convert nibble to hexadecimal digit character
2084 char nibbleToHex(u8 n) MUST_CHECK;
2085 // escape string to become compilable in a C source code
2086 char* cEscapeS(const char *S) MUST_CHECK;
2087 char* bCEscapeS(char *dest, const char *S) MUST_CHECK;
2088 char* bLCEscapeS(char *dest, size_t destSize, const char *S) MUST_CHECK;
2089 size_t cEscapeLenS(const char *s) MUST_CHECK;
2090 
2091 // true when string is a number (integer or float)
2092 bool isNumber(const char *string) MUST_CHECK;
2093 
2094 // true when string is an integer
2095 bool isInt(const char *string) MUST_CHECK;
2096 
2097 // parseInt
2098 int64_t parseInt(const char *string) MUST_CHECK;
2099 int64_t parseIntChar(char c) MUST_CHECK;
2100 int64_t parseI64(const char *string) MUST_CHECK;
2101 int64_t parseI64Char(char c) MUST_CHECK;
2102 
2103 // parseDouble
2104 double parseDouble(const char *string) MUST_CHECK;
2105 double parseDoubleChar(char c) MUST_CHECK;
2106 
2107 // parse hexadecimal string: 0xff
2108 uint64_t parseHex(const char *string) MUST_CHECK;
2109 // TODO parseHexChar
2110 
2111 // convert int to string
2112 char *intToS(int64_t n) MUST_CHECK;
2113 char *bIntToS(char *s, int64_t n) MUST_CHECK;
2114 
2115 // convert double to string
2116 char *doubleToS(double n) MUST_CHECK;
2117 char *bDoubleToS(char *s, double n) MUST_CHECK;
2118 
2119 // length
2120 size_t lenS(const char *string) MUST_CHECK;
2121 // string buffer size: strlen+1
2122 size_t sizeS(const char *string) MUST_CHECK;
2123 
2127 #define toUpper(c) ((c) = toupper(c), c)
2128 
2129 // duplicate and upper case
2130 char *upperS(const char *string) MUST_CHECK;
2131 char *iUpperS(char **string) MUST_CHECK;
2132 char *bUpperS(char *string) MUST_CHECK;
2133 
2137 #define toLower(c) ((c) = tolower(c), c)
2138 
2139 // duplicate and lower case
2140 char *lowerS(const char *string) MUST_CHECK;
2141 char *iLowerS(char **string) MUST_CHECK;
2142 char *bLowerS(char *string) MUST_CHECK;
2143 
2144 // duplicate and trim
2145 char *trimS(const char *string) MUST_CHECK;
2146 char *iTrimS(char **string) MUST_CHECK;
2147 char *bTrimS(char *string) MUST_CHECK;
2148 char *lTrimS(const char *string) MUST_CHECK;
2149 char *iLTrimS(char **string) MUST_CHECK;
2150 char *bLTrimS(char *string) MUST_CHECK;
2151 char *rTrimS(const char *string) MUST_CHECK;
2152 char *iRTrimS(char **string) MUST_CHECK;
2153 char *bRTrimS(char *string) MUST_CHECK;
2154 
2155 // remove successive repetitions of char c
2156 char *uniqS(const char *string, char c) MUST_CHECK;
2157 char *iUniqS(char **string, char c) MUST_CHECK;
2158 char *bUniqS(char *string, char c) MUST_CHECK;
2159 #define uniqSlash(s) uniqS(s, '/')
2160 #define iUniqSlash(s) iUniqS(&(s), '/')
2161 #define bUniqSlash(s) bUniqS(s, '/')
2162 
2163 // ignore case and remove successive repetitions of char c
2164 char *icUniqS(const char *string, char c) MUST_CHECK;
2165 char *iicUniqS(char **string, char c) MUST_CHECK;
2166 char *bicUniqS(char *string, char c) MUST_CHECK;
2167 
2168 // repeat string count times
2169 char *repeatS(const char *string, size_t count) MUST_CHECK;
2170 char *iRepeatS(char **string, size_t count) MUST_CHECK;
2171 char *bRepeatS(char *dest, const char *string, size_t count) MUST_CHECK;
2172 char *bLRepeatS(char *dest, size_t destSize, const char *string, size_t count) MUST_CHECK;
2173 char *repeatCharS(char c, size_t count) MUST_CHECK;
2174 char *bRepeatCharS(char *dest, char c, size_t count) MUST_CHECK;
2175 char *bLRepeatCharS(char *dest, size_t destSize, char c, size_t count) MUST_CHECK;
2176 
2177 // length of string repeated count times
2178 ssize_t repeatLenS(const char *string, size_t count) MUST_CHECK;
2179 
2180 // ellipsisStart string
2181 char *ellipsisStartS(const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
2182 char *iEllipsisStartS(char **string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
2183 char *bEllipsisStartS(char *dest, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
2184 char *bLEllipsisStartS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
2185 char *ellipsisStartCharS(const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
2186 char *iEllipsisStartCharS(char **string, size_t targetLength, char ellipsisChar) MUST_CHECK;
2187 char *bEllipsisStartCharS(char *dest, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
2188 char *bLEllipsisStartCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
2189 
2190 // length of string after ellipsis
2191 ssize_t ellipsisLenS(const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
2192 
2193 // ellipsisEnd string
2194 char *ellipsisEndS(const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
2195 char *iEllipsisEndS(char **string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
2196 char *bEllipsisEndS(char *dest, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
2197 char *bLEllipsisEndS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
2198 char *ellipsisEndCharS(const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
2199 char *iEllipsisEndCharS(char **string, size_t targetLength, char ellipsisChar) MUST_CHECK;
2200 char *bEllipsisEndCharS(char *dest, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
2201 char *bLEllipsisEndCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
2202 
2203 // padStart string
2204 char *padStartS(const char *string, size_t targetLength, const char *padString) MUST_CHECK;
2205 char *iPadStartS(char **string, size_t targetLength, const char *padString) MUST_CHECK;
2206 char *bPadStartS(char *dest, const char *string, size_t targetLength, const char *padString) MUST_CHECK;
2207 char *bLPadStartS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *padString) MUST_CHECK;
2208 char *padStartCharS(const char *string, size_t targetLength, char padChar) MUST_CHECK;
2209 char *iPadStartCharS(char **string, size_t targetLength, char padChar) MUST_CHECK;
2210 char *bPadStartCharS(char *dest, const char *string, size_t targetLength, char padChar) MUST_CHECK;
2211 char *bLPadStartCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char padChar) MUST_CHECK;
2212 
2213 // length of string after padStart
2214 ssize_t padStartLenS(const char *string, size_t targetLength, const char *padString) MUST_CHECK;
2215 
2216 // padEnd string
2217 char *padEndS(const char *string, size_t targetLength, const char *padString) MUST_CHECK;
2218 char *iPadEndS(char **string, size_t targetLength, const char *padString) MUST_CHECK;
2219 char *bPadEndS(char *dest, const char *string, size_t targetLength, const char *padString) MUST_CHECK;
2220 char *bLPadEndS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *padString) MUST_CHECK;
2221 char *padEndCharS(const char *string, size_t targetLength, char padChar) MUST_CHECK;
2222 char *iPadEndCharS(char **string, size_t targetLength, char padChar) MUST_CHECK;
2223 char *bPadEndCharS(char *dest, const char *string, size_t targetLength, char padChar) MUST_CHECK;
2224 char *bLPadEndCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char padChar) MUST_CHECK;
2225 
2226 // length of string after padEnd
2227 ssize_t padEndLenS(const char *string, size_t targetLength, const char *padString) MUST_CHECK;
2228 
2229 // get char at python index
2230 char getS(const char *string, int64_t index) MUST_CHECK;
2231 
2232 // set char at python index
2233 char *setS(char *string, int64_t index, char c) MUST_CHECK;
2234 
2235 // swap characters in a string
2236 char *swapS(char *string, int64_t index1, int64_t index2) MUST_CHECK;
2237 char *iSwapS(char **string, int64_t index1, int64_t index2) MUST_CHECK;
2238 char *bSwapS(char *string, int64_t index1, int64_t index2) MUST_CHECK;
2239 char *bLSwapS(char *string, size_t size, int64_t index1, int64_t index2) MUST_CHECK;
2240 
2241 // slice string
2242 // function to slice parts of a string [1:10] - python style indexes 0..len-1 -1..-len+1
2243 char *sliceS(const char *string, int64_t start, int64_t end) MUST_CHECK;
2244 char *iSliceS(char **string, int64_t start, int64_t end) MUST_CHECK;
2245 char *bSliceS(char *string, int64_t start, int64_t end) MUST_CHECK;
2246 char *bLSliceS(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK;
2247 
2248 // crop string (slice+del)
2249 char *cropS(char *string, int64_t start, int64_t end) MUST_CHECK;
2250 char *iCropS(char **string, int64_t start, int64_t end) MUST_CHECK;
2251 char cropElemS(char *string, int64_t index) MUST_CHECK;
2252 char iCropElemS(char **string, int64_t index) MUST_CHECK;
2253 
2254 // insert string in string
2255 char *insertS(const char *string, int64_t index, const char *toInsert) MUST_CHECK;
2256 char *insertNFreeS(const char *string, int64_t index, char *toInsert) MUST_CHECK;
2257 char *iInsertS(char **string, int64_t index, const char *toInsert) MUST_CHECK;
2258 char *iInsertNFreeS(char **string, int64_t index, char *toInsert) MUST_CHECK;
2259 char *bInsertS(char *string, int64_t index, const char *toInsert) MUST_CHECK;
2260 char *bLInsertS(char *string, size_t stringSize, int64_t index, const char *toInsert) MUST_CHECK;
2261 
2262 // inject a char in string
2263 char *injectS(const char *string, int64_t index, char toInject) MUST_CHECK;
2264 char *iInjectS(char **string, int64_t index, char toInject) MUST_CHECK;
2265 char *bInjectS(char *string, int64_t index, char toInject) MUST_CHECK;
2266 char *bLInjectS(char *string, size_t stringSize, int64_t index, char toInject) MUST_CHECK;
2267 
2268 // del string
2269 // function to delete parts of a string [1:10] - python style indexes 0..len-1 -1..-len+1
2270 char *delS(const char *string, int64_t start, int64_t end) MUST_CHECK;
2271 char *iDelS(char **string, int64_t start, int64_t end) MUST_CHECK;
2272 char *bDelS(char *string, int64_t start, int64_t end) MUST_CHECK;
2273 char *bLDelS(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK;
2274 
2275 // del a character in string
2276 char *delElemS(const char *string, int64_t index) MUST_CHECK;
2277 char *iDelElemS(char **string, int64_t index) MUST_CHECK;
2278 char *bDelElemS(char *string, int64_t index) MUST_CHECK;
2279 char *bLDelElemS(char *string, size_t stringSize, int64_t index) MUST_CHECK;
2280 
2281 // find substring
2282 char *findS(const char *string, const char *needle) MUST_CHECK;
2283 char *findCharS(const char *string, char c) MUST_CHECK;
2284 ssize_t indexOfS(const char *string, const char *needle) MUST_CHECK;
2285 ssize_t indexOfCharS(const char *string, char c) MUST_CHECK;
2286 
2287 // true when needle is found
2288 bool hasS(const char *string, const char *needle) MUST_CHECK;
2289 bool hasCharS(const char *string, char c) MUST_CHECK;
2290 
2291 // ignore case find substring
2292 char *icFindS(const char *string, const char *needle) MUST_CHECK;
2293 char *icFindCharS(const char *string, char c) MUST_CHECK;
2294 ssize_t icIndexOfS(const char *string, const char *needle) MUST_CHECK;
2295 ssize_t icIndexOfCharS(const char *string, char c) MUST_CHECK;
2296 
2297 // ignore case, true when needle is found
2298 bool icHasS(const char *string, const char *needle) MUST_CHECK;
2299 bool icHasCharS(const char *string, char c) MUST_CHECK;
2300 
2301 // parse s string with delim - work like strtok_r from stdlib
2302 char *tokS(char *s, const char *delim, char **saveptr) MUST_CHECK;
2303 
2304 // ignore case and parse s string with delim - work like strtok_r from stdlib
2305 char *icTokS(char *s, const char *delim, char **saveptr) MUST_CHECK;
2306 
2307 //
2308 // UTF8 string functions
2309 //
2310 
2311 // rune is a 32 bit unicode integer
2312 typedef int rune;
2313 
2314 // character length of UTF-8 encoded string
2315 size_t lenUTF8(const char *s) MUST_CHECK;
2316 size_t bLLenUTF8(const char *s, size_t maxSize) MUST_CHECK;
2317 
2318 // is string valid UTF-8 encoded string
2319 bool isUTF8(const char * string) MUST_CHECK;
2320 bool bLIsUTF8(const char * string, size_t stringSize) MUST_CHECK;
2321 
2322 // is string a valid UTF-8 code point
2323 bool isCodeUTF8(const char *code) MUST_CHECK;
2324 
2325 extern const uint8_t codeSzUTF8[256];
2326 
2328 #define codeSizeUTF8(utf8) codeSzUTF8[*(const uint8_t *)(utf8)]
2329 
2331 #define nextCodeUTF8(utf8) ((utf8) + codeSizeUTF8(utf8))
2332 
2334 #define nxtCodeUTF8(utf8) EVA(utf8, nextCodeUTF8(utf8))
2335 #define nxCodeUTF8(utf8) (utf8 = nextCodeUTF8(utf8))
2336 
2337 // next code point, works only when utf8 points to a valid code point
2338 const char *nextUTF8(const char *utf8) MUST_CHECK;
2339 const char *bLNextUTF8(const char *string, size_t utf8Size, const char *utf8) MUST_CHECK;
2340 
2341 // find next code point even when utf8 points inside a code point
2342 const char *findNextUTF8(const char *string, size_t utf8Size, const char *utf8) MUST_CHECK;
2343 
2344 // previous code point, undefined behavior when utf8 points to the start of the string
2345 const char *prevUTF8(const char *utf8) MUST_CHECK;
2346 
2347 // previous code point
2348 const char *bPrevUTF8(const char *string, const char *utf8) MUST_CHECK;
2349 
2350 // character index to pointer
2351 const char *idx2PtrUTF8(const char *utf8, int64_t index) MUST_CHECK;
2352 const char *bLIdx2PtrUTF8(const char *utf8, size_t utf8Size, int64_t index) MUST_CHECK;
2353 
2354 // pointer to character index
2355 int64_t ptr2IdxUTF8(const char *utf8, const char *pos) MUST_CHECK;
2356 int64_t bPtr2IdxUTF8(const char *start, const char *utf8, const char *pos) MUST_CHECK;
2357 int64_t bLPtr2IdxUTF8(const char *utf8, size_t utf8Size, const char *pos) MUST_CHECK;
2358 int64_t bLPtr2NegIdxUTF8(const char *utf8, size_t utf8Size, const char *pos) MUST_CHECK;
2359 
2360 // make new valid UTF-8 encoded string
2361 char *makeValidUTF8(const char *utf8) MUST_CHECK;
2362 // make utf8 a valid UTF-8 encoded string
2363 char *bMakeValidUTF8(char *utf8) MUST_CHECK;
2364 char *nMakeValidUTF8(const char *utf8, size_t utf8Len) MUST_CHECK;
2365 char *bNMakeValidUTF8(char *dst, const char *utf8, size_t utf8Len) MUST_CHECK;
2366 char *bLMakeValidUTF8(char *dst, size_t dstSize, const char *utf8) MUST_CHECK;
2367 char *bLNMakeValidUTF8(char *dst, size_t dstSize, const char *utf8, size_t utf8Len) MUST_CHECK;
2368 
2369 // strncpy where srcLen is number of characters
2370 char *strNCpyUTF8(char *dst, const char *src, size_t srcLen) MUST_CHECK;
2371 
2372 // strLCpy for UTF-8 encoded strings
2373 char *strLCpyUTF8(char *dst, size_t dstSize, const char *src) MUST_CHECK;
2374 
2375 // strncat where srcLen is number of characters
2376 char *strNCatUTF8(char *dst, const char *src, size_t srcLen) MUST_CHECK;
2377 
2378 // strLCat for UTF-8 encoded strings
2379 char *strLCatUTF8(char *dst, size_t dstSize, const char *src) MUST_CHECK;
2380 
2381 // strLNCat for UTF-8 encoded strings
2382 char *strLNCatUTF8(char *dst, size_t dstSize, const char *src, size_t srcLen) MUST_CHECK;
2383 
2384 // TODO
2385 char* icReplaceUTF8(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
2386 // TODO
2387 char *icReplaceCharSUTF8(const char *s, char olds, const char *news, size_t max) MUST_CHECK;
2388 // TODO
2389 char *icReplaceSCharUTF8(const char *s, const char *olds, char news, size_t max) MUST_CHECK;
2390 // TODO
2391 char* iicReplaceUTF8(char **s, const char *olds, const char *news, size_t max) MUST_CHECK;
2392 // TODO
2393 char *iicReplaceCharSUTF8(char **s, char olds, const char *news, size_t max) MUST_CHECK;
2394 // TODO
2395 char *iicReplaceSCharUTF8(char **s, const char *olds, char news, size_t max) MUST_CHECK;
2396 // TODO
2397 char* bicReplaceUTF8(char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
2398 // TODO
2399 char* bLicReplaceUTF8(char *s, size_t sSize, const char *olds, const char *news, size_t max) MUST_CHECK;
2400 // TODO
2401 char *icReplaceManyUTF8F(const char *paramType, ...) MUST_CHECK;
2402 // TODO
2403 char *iicReplaceManyUTF8F(char **s, char *paramType, ...) MUST_CHECK;
2404 // TODO
2405 char *bicReplaceManyUTF8F(char *s, char *paramType, ...) MUST_CHECK;
2406 // TODO
2407 char *bLicReplaceManyUTF8F(char *s, size_t sSize, char *paramType, ...) MUST_CHECK;
2408 
2409 // UTF8 encoded string Index Equal
2410 bool eqIUTF8(const char *string1, const char *string2, int64_t index) MUST_CHECK;
2411 
2412 // UTF8 encoded string Index Equal
2413 bool eqICharUTF8(const char *string1, char c, int64_t index) MUST_CHECK;
2414 
2415 // ignore case UTF8 encoded string Equal
2416 bool icEqUTF8(const char *string1, const char *string2) MUST_CHECK;
2417 bool icEqCharUTF8(char c, const char *string2) MUST_CHECK;
2418 bool icEqUTF8Char(const char *string1, char c) MUST_CHECK;
2419 
2420 // TODO
2421 bool icEqIUTF8(const char *string1, const char *string2, int64_t index) MUST_CHECK;
2422 // TODO
2423 bool icEqICharUTF8(const char *string1, char c, int64_t index) MUST_CHECK;
2424 
2425 // starts with for UTF-8 encoded string
2426 bool icStartsWithUTF8(const char *string1, const char *string2) MUST_CHECK;
2427 
2428 // ends with for UTF-8 encoded string
2429 bool icEndsWithUTF8(const char *string1, const char *string2) MUST_CHECK;
2430 
2431 // ignore case count UTF8 encoded String
2432 ssize_t icCountUTF8(const char *s, const char *needle) MUST_CHECK;
2433 
2434 // UTF-8 code point to rune
2435 rune code2RuneUTF8(const char *code) MUST_CHECK;
2436 rune code2RuneLUTF8(const char *code, uint8_t *n) MUST_CHECK;
2437 
2438 // rune to UTF-8 code point
2439 size_t bRune2CodeUTF8(char *dst, rune c) MUST_CHECK;
2440 
2441 // rune length as UTF-8 code point
2442 uint8_t runeLenUTF8(rune r) MUST_CHECK;
2443 
2444 // rune toupper UTF8
2445 rune toupperUTF8(rune c) MUST_CHECK;
2446 
2447 // upper case UTF-8 encoded string
2448 char *upperUTF8(const char *string) MUST_CHECK;
2449 char *iUpperUTF8(char **string) MUST_CHECK;
2450 // TODO
2451 char *bUpperUTF8(char *string) MUST_CHECK;
2452 
2453 // rune tolower UTF8
2454 rune tolowerUTF8(rune c) MUST_CHECK;
2455 
2456 // lower case UTF-8 String
2457 char *lowerUTF8(const char *string) MUST_CHECK;
2458 char *iLowerUTF8(char **string) MUST_CHECK;
2459 // TODO
2460 char *bLowerUTF8(char *string) MUST_CHECK;
2461 
2462 // transform UTF-8 string to make it comparable regardless of case
2463 char *casefoldUTF8(const char *utf8) MUST_CHECK;
2464 
2465 // uniquify code point in UTF-8 String
2466 char *uniqUTF8(const char *string, const char *code) MUST_CHECK;
2467 char *iUniqUTF8(char **string, const char *code) MUST_CHECK;
2468 char *bUniqUTF8(char *string, const char *code) MUST_CHECK;
2469 // TODO
2470 char *icUniqUTF8(const char *string, const char *code) MUST_CHECK;
2471 // TODO
2472 char *iicUniqUTF8(char **string, const char *code) MUST_CHECK;
2473 // TODO
2474 char *bicUniqUTF8(char *string, char c) MUST_CHECK;
2475 
2476 // get rune in UTF8 encoded string
2477 rune getUTF8(const char *string, int64_t index) MUST_CHECK;
2478 
2479 // TODO
2480 char *setUTF8(char *string, int64_t index, rune c) MUST_CHECK;
2481 
2482 // slice UTF8 encoded String
2483 char *sliceUTF8(const char *string, int64_t start, int64_t end) MUST_CHECK;
2484 char *iSliceUTF8(char **string, int64_t start, int64_t end) MUST_CHECK;
2485 char *bSliceUTF8(char *string, int64_t start, int64_t end) MUST_CHECK;
2486 char *bLSliceUTF8(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK;
2487 
2488 // insert string in UTF8 encoded string at index
2489 char *insertUTF8(const char *string, int64_t index, const char *toInsert) MUST_CHECK;
2490 char *insertNFreeUTF8(const char *string, int64_t index, char *toInsert) MUST_CHECK;
2491 char *iInsertUTF8(char **string, int64_t index, const char *toInsert) MUST_CHECK;
2492 char *iInsertNFreeUTF8(char **string, int64_t index, char *toInsert) MUST_CHECK;
2493 char *bInsertUTF8(char *string, int64_t index, const char *toInsert) MUST_CHECK;
2494 char *bLInsertUTF8(char *string, size_t stringSize, int64_t index, const char *toInsert) MUST_CHECK;
2495 
2496 // delete UTF8 encoded string
2497 char *delUTF8(const char *string, int64_t start, int64_t end) MUST_CHECK;
2498 char *iDelUTF8(char **string, int64_t start, int64_t end) MUST_CHECK;
2499 char *bDelUTF8(char *string, int64_t start, int64_t end) MUST_CHECK;
2500 char *bLDelUTF8(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK;
2501 
2502 // indexOf UTF8 encoded String
2503 ssize_t indexOfUTF8(const char *string, const char *needle) MUST_CHECK;
2504 // TODO
2505 ssize_t icIndexOfUTF8(const char *string, const char *needle) MUST_CHECK;
2506 
2507 // ignore case has UTF8 encoded String
2508 bool icHasUTF8(const char *string, const char *needle) MUST_CHECK;
2509 
2510 // TODO
2511 char *icTokUTF8(const char *s, const char *delim, char **saveptr) MUST_CHECK;
2512 
2513 // TODO
2514 char **icExtractUTF8(const char *string, const char* delim1, const char* delim2) MUST_CHECK;
2515 char **icExtractCharSUTF8(const char *string, char delim1, const char* delim2) MUST_CHECK;
2516 char **icExtractSCharUTF8(const char *string, const char* delim1, char delim2) MUST_CHECK;
2517 
2518 // ignore case list Sort UTF8 encoded String
2519 char **icListSortUTF8(char **list) MUST_CHECK;
2520 char **iicListSortUTF8(char ***list) MUST_CHECK;
2521 
2522 // ignore case list Equal UTF8 encoded String
2523 bool icListEqUTF8(char **list1, char **list2) MUST_CHECK;
2524 
2525 // ignore case and return true when list has UTF8 encoded string
2526 bool icListHasUTF8(char **list, const char *string) MUST_CHECK;
2527 
2528 // ignore case and return index of UTF8 encoded string in list
2529 ssize_t icListIndexOfUTF8(char **list, const char *string) MUST_CHECK;
2530 
2531 // ignore case list binary search UTF8 encoded string
2532 ssize_t icListBinarySearchUTF8(char **list, const char *string) MUST_CHECK;
2533 
2534 // ignore case and uniquify UTF8 encoded elements of list
2535 char **icListUniqUTF8(char **list) MUST_CHECK;
2536 char **iicListUniqUTF8(char ***list) MUST_CHECK;
2537 
2538 //
2539 // End UTF8 string functions
2540 //
2541 
2542 
2543 // create empty string
2544 #define emptyS(string) \
2545  string = strdup("");
2546 char *emptySF(void) MUST_CHECK;
2547 char *iEmptySF(char **string) MUST_CHECK;
2548 // string buffer empty - set 0 at index 0
2549 #define bEmptyS(string) \
2550  (string)[0] = 0
2551 
2552 // is empty string
2553 bool isEmptyS(const char *string) MUST_CHECK;
2554 
2558 #define orS(string, alternative) \
2559  !isEmptyS(string) ? (string) : (alternative)
2560 
2561 // true when string is empty or white spaces
2562 bool isBlankS(const char *string) MUST_CHECK;
2563 
2567 #define orBlankS(string, alternative) \
2568  !isBlankS(string) ? (string) : (alternative)
2569 
2573 #define nS(string) \
2574  (string) ? (string) : ""
2575 
2579 #define nAS(string, alternative) \
2580  (string) ? (string) : (alternative)
2581 
2582 
2583 // convert python index (int, positive and negative) to always positive index (uint), this function is more generic than listIntIndexS
2584 ssize_t intIndex(int64_t index, int64_t length);
2585 
2586 // create empty list
2587 #define listEmptyS(list) \
2588  do {\
2589  list = malloc(1 * sizeof(char *)); \
2590  if (list) list[0] = NULL; \
2591  } while(0);
2592 
2593 char **listEmptySF(void) MUST_CHECK;
2594 char **iListEmptySF(char ***list) MUST_CHECK;
2595 
2596 // false when there are elements in the list
2597 bool listIsEmptyS(char **list) MUST_CHECK;
2598 
2599 // false when there are non blank elements in the list
2600 bool listIsBlankS(char **list) MUST_CHECK;
2601 
2602 // String Lists
2603 // createList(...)
2604 char **listCreateSF(const char *paramType, ...) MUST_CHECK;
2605 #define listCreateS(...) listCreateSF("", __VA_ARGS__, NULL)
2606 
2607 // copy array to new list
2608 char **listFromArrayS(char **array, size_t size) MUST_CHECK;
2609 char **listFromCArrayS(const char **array, size_t size) MUST_CHECK;
2610 
2611 // push and pop (append) str
2612 // modifies the list
2613 char **listPushS(char ***list, const char *s) MUST_CHECK;
2614 char **listPushCharS(char ***list, char c) MUST_CHECK;
2615 char **iListPushS(char ***list, char *s) MUST_CHECK;
2616 
2617 // copy last string and free it in the list
2618 char *listPopS(char ***list) MUST_CHECK;
2619 
2620 // prepend and dequeue (append) str
2621 // modifies the list
2622 char **listPrependS(char ***list, const char *s) MUST_CHECK;
2623 char **listPrependCharS(char ***list, char c) MUST_CHECK;
2624 char **iListPrependS(char ***list, char *s) MUST_CHECK;
2625 
2626 // copy fist string and free it in the list
2627 char *listDequeueS(char ***list) MUST_CHECK;
2628 
2629 // freeList
2630 void listFreeS(char **list);
2631 
2632 // free many char**
2633 void listFreeManySF(char **paramType, ...);
2634 #define listFreeManyS(...) listFreeManySF(NULL, __VA_ARGS__, NULL)
2635 
2636 // length
2637 size_t listLengthS(char **list) MUST_CHECK;
2638 size_t listLengthCS(const char **list) MUST_CHECK;
2639 
2640 // list length as a single string
2641 ssize_t listStrLengthS(char **list) MUST_CHECK;
2642 
2643 // convert python index (int) to always positive index (uint)
2644 ssize_t listIntIndexS(char **list, int64_t index) MUST_CHECK;
2645 
2646 // pointer to the char* at python index
2647 char **listAddrS(char **list, int64_t index) MUST_CHECK;
2648 
2649 // list get - get a string at python index
2650 char *listGetS(char **list, int64_t index) MUST_CHECK;
2651 char *iListGetS(char **list, int64_t index) MUST_CHECK;
2652 char *listGetCS(const char **list, int64_t index) MUST_CHECK;
2653 const char *iListGetCS(const char **list, int64_t index) MUST_CHECK;
2654 
2655 // list set - replace a string at python index
2656 char **listSetS(char **list, int64_t index, const char *s) MUST_CHECK;
2657 char **listSetCharS(char **list, int64_t index, char c) MUST_CHECK;
2658 char **iListSetS(char **list, int64_t index, char *s) MUST_CHECK;
2659 
2660 // swap elements in a list
2661 char **listSwapS(char **list, int64_t index1, int64_t index2) MUST_CHECK;
2662 char **iListSwapS(char **list, int64_t index1, int64_t index2) MUST_CHECK;
2663 
2664 // split
2665 char **split(const char *string, const char* delim) MUST_CHECK;
2666 char **splitS(const char *string, const char* delim) MUST_CHECK;
2667 char **splitChar(const char *string, char delim) MUST_CHECK;
2668 
2669 // ignore case split
2670 char **icSplit(const char *string, const char* delim) MUST_CHECK;
2671 char **icSplitS(const char *string, const char* delim) MUST_CHECK;
2672 char **icSplitChar(const char *string, char delim) MUST_CHECK;
2673 
2674 // list length after joined with delimiter
2675 ssize_t joinLength(char **list, const char* delim) MUST_CHECK;
2676 
2677 // join
2678 char *join(char **list, const char* delim) MUST_CHECK;
2679 char *joinS(char **list, const char* delim) MUST_CHECK;
2680 char *joinCS(const char **list, const char* delim) MUST_CHECK;
2681 char *joinChar(char **list, char delim) MUST_CHECK;
2682 char *bJoin(char *string, char **list, const char* delim) MUST_CHECK;
2683 char *bJoinChar(char *string, char **list, char delim) MUST_CHECK;
2684 char *bLJoin(char *string, size_t stringSize, char **list, const char* delim) MUST_CHECK;
2685 char *bLJoinChar(char *string, size_t stringSize, char **list, char delim) MUST_CHECK;
2686 
2687 // extract string
2688 char **extractS(const char *string, const char* delim1, const char* delim2) MUST_CHECK;
2689 char **extractCharSS(const char *string, char delim1, const char* delim2) MUST_CHECK;
2690 char **extractSCharS(const char *string, const char* delim1, char delim2) MUST_CHECK;
2691 char **extractCharCharS(const char *string, char delim1, char delim2) MUST_CHECK;
2692 
2693 // ignore case extract string
2694 char **icExtractS(const char *string, const char* delim1, const char* delim2) MUST_CHECK;
2695 char **icExtractCharSS(const char *string, char delim1, const char* delim2) MUST_CHECK;
2696 char **icExtractSCharS(const char *string, const char* delim1, char delim2) MUST_CHECK;
2697 char **icExtractCharCharS(const char *string, char delim1, char delim2) MUST_CHECK;
2698 
2699 // duplicate list
2700 char **listDupS(char **list) MUST_CHECK;
2701 char **listDupCS(const char **list) MUST_CHECK;
2702 char **iListDupS(char **list) MUST_CHECK;
2703 
2704 // duplicate and reverse list
2705 char **listReverseS(char **list) MUST_CHECK;
2706 char **iListReverseS(char ***list) MUST_CHECK;
2707 
2708 // listCatS: f(l1, l2, l3)
2709 char **listCatSF(char **paramType, ...) MUST_CHECK;
2710 #define listCatS(...) listCatSF(NULL, __VA_ARGS__, NULL)
2711 
2712 // append lists
2713 char **listAppendS(char ***list1, char **list2) MUST_CHECK;
2714 char **iListAppendS(char ***list1, char **list2) MUST_CHECK;
2715 char **iListAppendNSmashS(char ***list1, char **list2) MUST_CHECK;
2716 
2717 // prepend list at the start and shift existing elements
2718 char **listShiftS(char ***list1, char **list2) MUST_CHECK;
2719 char **iListShiftS(char ***list1, char **list2) MUST_CHECK;
2720 char **iListShiftNSmashS(char ***list1, char **list2) MUST_CHECK;
2721 
2722 // add lists
2723 char **listAddS(char **list1, char **list2);
2724 char **listAddCS(char **list1, const char **list2);
2725 
2726 // slice - python style indexes 0..len-1 -1..-len+1
2727 char **listSliceS(char **list, int64_t start, int64_t end) MUST_CHECK;
2728 char **iListCopyS(char **list, int64_t start, int64_t end) MUST_CHECK;
2729 char **iListSliceS(char ***list, int64_t start, int64_t end) MUST_CHECK;
2730 
2731 // crop list (slice+del)
2732 char **listCropS(char **list, int64_t start, int64_t end) MUST_CHECK;
2733 char **iListCropS(char ***list, int64_t start, int64_t end) MUST_CHECK;
2734 char *listCropElemS(char **list, int64_t index) MUST_CHECK;
2735 char *iListCropElemS(char ***list, int64_t index) MUST_CHECK;
2736 
2737 // insert list in list
2738 char **listInsertS(char **list, int64_t index, char **toInsert) MUST_CHECK;
2739 char **iListInsertS(char ***list, int64_t index, char **toInsert) MUST_CHECK;
2740 char **iListInsertNFreeS(char ***list, int64_t index, char **toInsert) MUST_CHECK;
2741 
2742 // inject string in list
2743 char **listInjectS(char **list, int64_t index, char *toInject) MUST_CHECK;
2744 char **listInjectCharS(char **list, int64_t index, char toInject) MUST_CHECK;
2745 char **iListInjectS(char ***list, int64_t index, char *toInject) MUST_CHECK;
2746 char **iListInjectCharS(char ***list, int64_t index, char toInject) MUST_CHECK;
2747 
2748 // del - python style indexes 0..len-1 -1..-len+1
2749 char **listDelS(char **list, int64_t start, int64_t end) MUST_CHECK;
2750 char **iListDelS(char ***list, int64_t start, int64_t end) MUST_CHECK;
2751 char **iListRemoveS(char ***list, int64_t start, int64_t end);
2752 
2753 // del element in list
2754 char **listDelElemS(char **list, int64_t index) MUST_CHECK;
2755 char **iListDelElemS(char ***list, int64_t index) MUST_CHECK;
2756 char **iListRemoveElemS(char ***list, int64_t index) MUST_CHECK;
2757 
2758 // print list
2759 int listPrintS(char **list) MUST_CHECK;
2760 int listPrintCS(const char **list) MUST_CHECK;
2761 
2765 #define forever while(1)
2766 
2772 #define range(index, maxCount) \
2773  ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
2774  for (size_t index = 0 ; index < UNIQVAR(maxCnt) ; index++)
2775 
2780 #define rangeInf(index) \
2781  for (size_t index = 0 ;; index++)
2782 
2786 #define rangeDown(index, maxCount) \
2787  for (ssize_t index = (maxCount)-1 ; index >= 0 ; index--)
2788 
2794 #define rangeDownTo(index, maxCount, to) \
2795  ;ssize_t UNIQVAR(_to) = to;\
2796  for (ssize_t index = (maxCount)-1 ; index >= UNIQVAR(_to) ; index--)
2797 
2803 #define rangeFrom(index, from, maxCount) \
2804  ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
2805  for (size_t index = from ; index < UNIQVAR(maxCnt) ; index++)
2806 
2814 #define arange(index, array) range(index, ARRAY_SIZE(array))
2815 
2823 #define arangeDown(index, array) rangeDown(index, ARRAY_SIZE(array))
2824 
2832 #define arangeDownTo(index, array, to) rangeDownTo(index, ARRAY_SIZE(array), to)
2833 
2841 #define arangeFrom(index, from, array) rangeFrom(index, from, ARRAY_SIZE(array))
2842 
2854 #define circular(index, from, maxCount) \
2855  ;bool UNIQVAR(libsheepyInternalStatus) = true; \
2856  size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
2857  size_t UNIQVAR(frm) = (size_t)(from); \
2858  for (size_t index = UNIQVAR(frm) ; (index != UNIQVAR(frm)) || (UNIQVAR(libsheepyInternalStatus)); index == (UNIQVAR(maxCnt)-1) ? index = 0 : index++, UNIQVAR(libsheepyInternalStatus) = false)
2859 
2871 #define circularDown(index, from, maxCount) \
2872  ;bool UNIQVAR(libsheepyInternalStatus) = true; \
2873  size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
2874  size_t UNIQVAR(frm) = (size_t)(from); \
2875  for (size_t index = UNIQVAR(frm) ; (index != UNIQVAR(frm)) || (UNIQVAR(libsheepyInternalStatus)); index == 0 ? index = (UNIQVAR(maxCnt)-1) : index--, UNIQVAR(libsheepyInternalStatus) = false)
2876 
2882 #define rangeStep(index, maxCount, step) \
2883  ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
2884  for (size_t index = 0 ; index < UNIQVAR(maxCnt) ; index+=step)
2885 
2889 #define rangeDownStep(index, maxCount, step) \
2890  for (int64_t index = (maxCount)-1 ; index >= 0 ; index-=step)
2891 
2897 #define rangeFromStep(index, from, maxCount, step) \
2898  ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
2899  for (size_t index = from ; index < UNIQVAR(maxCnt) ; index+=(size_t)step)
2900 
2901 
2907 #define loop(maxCount) \
2908  ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
2909  for (size_t UNIQVAR(index) = 0 ; UNIQVAR(index) < UNIQVAR(maxCnt) ; UNIQVAR(index)++)
2910 
2916 #define loopDownTo(maxCount, to) \
2917  ;ssize_t UNIQVAR(_to) = to;\
2918  for (ssize_t UNIQVAR(index) = (maxCount)-1 ; UNIQVAR(index) >= UNIQVAR(_to) ; UNIQVAR(index)--)
2919 
2925 #define loopFrom(from, maxCount) \
2926  ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
2927  for (size_t UNIQVAR(index) = from ; UNIQVAR(index) < UNIQVAR(maxCnt) ; UNIQVAR(index)++)
2928 
2934 #define loopStep(maxCount, step) \
2935  ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
2936  for (size_t UNIQVAR(index) = 0 ; UNIQVAR(index) < UNIQVAR(maxCnt) ; UNIQVAR(index)+=step)
2937 
2943 #define loopFromStep(from, maxCount, step) \
2944  ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
2945  for (size_t UNIQVAR(index) = from ; UNIQVAR(index) < UNIQVAR(maxCnt) ; UNIQVAR(index)+=step)
2946 
2947 
2956 #define aForEach(array, element) \
2957  ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
2958  for (typeof(&array[0]) element = &array[0] ; UNIQVAR(libsheepyInternalIndex) < ARRAY_SIZE(array) ; UNIQVAR(libsheepyInternalIndex)++, element = &array[UNIQVAR(libsheepyInternalIndex)])
2959 
2971 #define aEnumerate(array, index, element) \
2972  ; size_t index = 0 ; \
2973  for (typeof(&array[0]) element = &array[0] ; index < ARRAY_SIZE(array) ; index++, element = &array[index])
2974 
2979 #define forEachCharP(list, element) \
2980  for (char **element=list ; *element != NULL ; element++)
2981 
2985 #define forEachCCharP(list, element) \
2986  for (const char **element=list ; *element != NULL ; element++)
2987 
2994 #define forEachS(list, element) \
2995  ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
2996  for (char *element = (list)[0]; (list)[UNIQVAR(libsheepyInternalIndex)]!= NULL ; UNIQVAR(libsheepyInternalIndex)++, element = (list)[UNIQVAR(libsheepyInternalIndex)])
2997 
3001 #define forEachCS(list, element) \
3002  ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
3003  for (const char *element = (list)[0]; (list)[UNIQVAR(libsheepyInternalIndex)]!= NULL ; UNIQVAR(libsheepyInternalIndex)++, element = (list)[UNIQVAR(libsheepyInternalIndex)])
3004 
3008 #define forEachType(type, list, element) \
3009  for (type **element=list ; *element != NULL ; element++)
3010 
3017 #define enumerateCharP(list, element, index) \
3018  ;size_t index = 0; \
3019  for (char **element=list; *element != NULL ; element++, index++)
3020 
3027 #define enumerateCCharP(list, element, index) \
3028  ;size_t index = 0; \
3029  for (const char **element=list; *element != NULL ; element++, index++)
3030 
3037 #define enumerateS(list, element, index) \
3038  ;size_t index = 0; \
3039  for (char *element=(list)[0]; element != NULL ; index++, element = (list)[index])
3040 
3047 #define enumerateCS(list, element, index) \
3048  ;size_t index = 0; \
3049  for (const char *element=(list)[0]; element != NULL ; index++, element = (list)[index])
3050 
3056 #define enumerateType(type, list, element, index) \
3057  ;size_t index = 0; \
3058  for (type **element=list; *element != NULL ; element++, index++)
3059 
3068 #define lForEach(node, startNode)\
3069  for(var node = startNode; node ; node = (node)->next)
3070 
3079 #define lForEachDown(node, startNode)\
3080  for(var node = startNode; node ; node = (node)->prev)
3081 
3082 #define lForEachPrev lForEachDown
3083 
3084 // user defined function for sort functions
3085 typedef int (*shCmpt)(const void * a, const void * b);
3086 
3087 // duplicate and sort
3088 char **listSortS(char **list) MUST_CHECK;
3089 char **iListSortS(char ***list) MUST_CHECK;
3090 char **listSortFS(char **list, shCmpt compareFunction) MUST_CHECK;
3091 char **iListSortFS(char ***list, shCmpt compareFunction) MUST_CHECK;
3092 
3093 // ignore case, duplicate and sort
3094 char **icListSortS(char **list) MUST_CHECK;
3095 char **iicListSortS(char ***list) MUST_CHECK;
3096 
3097 // open text file and return lines in list
3098 char **readText(const char *filePath) MUST_CHECK;
3099 
3100 // read opened text file and return lines in list
3101 // the file is left open
3102 char **readStream(FILE *fp) MUST_CHECK;
3103 
3104 // write text file
3105 bool writeText(const char *filePath, char **list) MUST_CHECK;
3106 bool writeCText(const char *filePath, const char **list) MUST_CHECK;
3107 
3108 // write buffer
3109 bool writeStream(FILE *fp, char **list) MUST_CHECK;
3110 bool writeCStream(FILE *fp, const char **list) MUST_CHECK;
3111 
3112 // append text to file
3113 bool appendText(const char *filePath, char **list) MUST_CHECK;
3114 bool appendCText(const char *filePath, const char **list) MUST_CHECK;
3115 
3116 // execOut
3117 char **execOut(const char *cmd) MUST_CHECK;
3118 // convenience define
3119 #define execOutf systemOutf
3120 #define execf systemf
3121 
3122 // system command with formatting
3123 char **systemOutf(const char *fmt, ...) MUST_CHECK;
3124 // convenience define
3125 #define systemOut execOut
3126 int systemf(const char *fmt, ...) MUST_CHECK;
3127 
3128 // system commands and log
3129 #define logSystem(cmd) funcbegin\
3130  var UNIQVAR(cm) = cmd;\
3131  logI("%s",UNIQVAR(cm));\
3132  system (UNIQVAR(cm));\
3133  funcend
3134 #define logExec logSystem
3135 #define logSystemOut(cmd) ({\
3136  var UNIQVAR(cm) = cmd;\
3137  logI("%s",UNIQVAR(cm));\
3138  systemOut(UNIQVAR(cm));\
3139  })
3140 #define logExecOut logSystemOut
3141 #define logSystemOutf(fmt, ...) ({\
3142  logI (fmt, __VA_ARGS__);\
3143  systemOutf(fmt, __VA_ARGS__);})
3144 #define logExecOutf logSystemOutf
3145 #define logSystemf(fmt, ...) ({\
3146  logI (fmt, __VA_ARGS__);\
3147  systemf(fmt, __VA_ARGS__);})
3148 #define logExecf logSystemf
3149 
3150 // run command and return exit code from command (not system return value like system, systemf and systemNFree)
3151 #define command(cmd) commandF(cmd, __LINE__, __func__, __FILE__)
3152 int commandF(const char *cmd, int line, const char *thisFunc, const char *thisFileName) MUST_CHECK;
3153 #define commandf(...) commandfF(__LINE__, __func__, __FILE__, __VA_ARGS__)
3154 int commandfF(int line, const char *thisFunc, const char *thisFileName, const char *fmt, ...) MUST_CHECK;
3155 #define commandNFree(cmd) commandNFreeF(cmd, __LINE__, __func__, __FILE__)
3156 int commandNFreeF(char *cmd, int line, const char *thisFunc, const char *thisFileName) MUST_CHECK;
3157 #define commandOut execOut
3158 #define commandOutf systemOutf
3159 
3160 // log then run command and return exit code from command (not system return value like system, systemf and systemNFree)
3161 #define logCommand(cmd) funcbegin\
3162  var UNIQVAR(cm) = cmd;\
3163  logI("%s",UNIQVAR(cm));\
3164  command (UNIQVAR(cm));\
3165  funcend
3166 
3167 #define logCommandf(fmt, ...) funcbegin\
3168  logI (fmt, __VA_ARGS__);\
3169  commandf(fmt, __VA_ARGS__);\
3170  funcend
3171 
3172 #define logCommandNFree(cmd) funcbegin\
3173  var UNIQVAR(cm) = cmd;\
3174  logI ("%s",UNIQVAR(cm));\
3175  commandNFree(UNIQVAR(cm));\
3176  funcend
3177 
3178 #define logCommandOut logExecOut
3179 #define logCommandOutf logExecOutf
3180 
3181 // compare lists
3182 bool listEqS(char **list1, char **list2) MUST_CHECK;
3183 bool listEqCS(char **list1, const char **list2) MUST_CHECK;
3184 bool listEqC1S(const char **list1, char **list2) MUST_CHECK;
3185 bool listEqCCS(const char **list1, const char **list2) MUST_CHECK;
3186 
3187 // has
3188 bool listHasS(char **list, const char *string) MUST_CHECK;
3189 bool listHasCS(const char **list, const char *string) MUST_CHECK;
3190 bool listHasCharS(char **list, char c) MUST_CHECK;
3191 bool listHasCharCS(const char **list, char c) MUST_CHECK;
3192 
3193 // indexOf
3194 ssize_t listIndexOfS(char **list, const char *string) MUST_CHECK;
3195 ssize_t listIndexOfCS(const char **list, const char *string) MUST_CHECK;
3196 ssize_t listIndexOfCharS(char **list, char c) MUST_CHECK;
3197 ssize_t listIndexOfCharCS(const char **list, char c) MUST_CHECK;
3198 
3199 // list binary search string
3200 ssize_t listBinarySearchS(char **list, const char *string) MUST_CHECK;
3201 ssize_t listBinarySearchCharS(char **list, char c) MUST_CHECK;
3202 
3203 // duplicate and uniquify
3204 char **listUniqS(char **list) MUST_CHECK;
3205 char **iListUniqS(char ***list) MUST_CHECK;
3206 
3207 // ignore case and compare lists
3208 bool icListEqS(char **list1, char **list2) MUST_CHECK;
3209 bool icListEqCS(char **list1, const char **list2) MUST_CHECK;
3210 bool icListEqC1S(const char **list1, char **list2) MUST_CHECK;
3211 bool icListEqCCS(const char **list1, const char **list2) MUST_CHECK;
3212 
3213 // ignore case has
3214 bool icListHasS(char **list, const char *string) MUST_CHECK;
3215 bool icListHasCharS(char **list, char c) MUST_CHECK;
3216 bool icListHasCS(const char **list, const char *string) MUST_CHECK;
3217 bool icListHasCharCS(const char **list, char c) MUST_CHECK;
3218 
3219 // ignore case indexOf
3220 ssize_t icListIndexOfS(char **list, const char *string) MUST_CHECK;
3221 ssize_t icListIndexOfCS(const char **list, const char *string) MUST_CHECK;
3222 ssize_t icListIndexOfCharS(char **list, char c) MUST_CHECK;
3223 ssize_t icListIndexOfCharCS(const char **list, char c) MUST_CHECK;
3224 
3225 // ignore case list binary search string
3226 ssize_t icListBinarySearchS(char **list, const char *string) MUST_CHECK;
3227 ssize_t icListBinarySearchCharS(char **list, char c) MUST_CHECK;
3228 
3229 // ignore case, duplicate and uniquify
3230 char **icListUniqS(char **list) MUST_CHECK;
3231 char **iicListUniqS(char ***list) MUST_CHECK;
3232 
3233 // duplicate and compact
3234 char **listCompactS(char **list) MUST_CHECK;
3235 char **iListCompactS(char ***list) MUST_CHECK;
3236 
3237 void btraceEnable(void);
3238 void btraceDisable(void);
3239 bool btraceConfig(void) MUST_CHECK;
3240 
3241 // get backtrace
3242 char **btrace(void);
3243 
3244 // print backtrace
3245 #if __APPLE__
3246 // TODO readelf missing in macOS
3247 #define logBtrace
3248 #else
3249 #define logBtrace char **UNIQVAR(r)=btrace();if(UNIQVAR(r)){logN("\n"BLD WHT"Backtrace:"RST);forEachS(UNIQVAR(r), element){logN(element);}listFreeS(UNIQVAR(r));logN("---");}
3250 #endif
3251 
3252 extern bool btraceCfg;
3253 
3255 #define logEBtrace if (btraceCfg) { char **UNIQVAR(r)=btrace();if(UNIQVAR(r)){logE("\n"BLD WHT"Backtrace:"RST);forEachS(UNIQVAR(r), element){logE(element);}listFreeS(UNIQVAR(r));logE("---");} }
3256 
3257 
3258 // **************************
3259 // void ** lists
3260 // **************************
3261 
3262 // create empty list
3263 #define listEmpty(list) \
3264  do {\
3265  list = malloc(1 * sizeof(void *)); \
3266  if (list) list[0] = NULL; \
3267  } while(0);
3268 
3269 void **listEmptyF(void) MUST_CHECK;
3270 void **iListEmptyF(void ***list) MUST_CHECK;
3271 
3272 // false when there are elements in the list
3273 bool listIsEmpty(void **list) MUST_CHECK;
3274 
3275 // createList(...)
3276 void **listCreateF(void *paramType, ...) MUST_CHECK;
3277 #define listCreate(...) listCreateF(NULL, __VA_ARGS__, NULL)
3278 
3279 // copy array to new list
3280 void **listFromArray(void **array, size_t size) MUST_CHECK;
3281 
3282 // push and pop (append) element
3283 // modifies the list
3284 void **listPush(void ***list, void *s) MUST_CHECK;
3285 
3286 // return last element and remove it from the list
3287 void *listPop(void ***list) MUST_CHECK;
3288 
3289 // prepend and dequeue (append) element
3290 // modifies the list
3291 void **listPrepend(void ***list, void *s) MUST_CHECK;
3292 
3293 // return fist element and remove it from the list
3294 void *listDequeue(void ***list) MUST_CHECK;
3295 
3296 // freeList
3297 void listFree(void **list);
3298 
3299 // free many void**
3300 void listFreeManyF(void **paramType, ...);
3301 #define listFreeMany(...) listFreeManyF(NULL, __VA_ARGS__, NULL)
3302 
3303 // length
3304 size_t listLength(void **list) MUST_CHECK;
3305 
3306 // list get - get an element at python index
3307 void *listGet(void **list, int64_t index) MUST_CHECK;
3308 
3309 // list set - replace a string at python index
3310 void **listSet(void **list, int64_t index, void *s) MUST_CHECK;
3311 
3312 // duplicate list
3313 void **listDup(void **list) MUST_CHECK;
3314 
3315 // duplicate and reverse list
3316 void **listReverse(void **list) MUST_CHECK;
3317 void **iListReverse(void ***list) MUST_CHECK;
3318 
3319 // listCatS: f(l1, l2, l3)
3320 void **listCatF(void **paramType, ...) MUST_CHECK;
3321 #define listCat(...) listCatF(NULL, __VA_ARGS__, NULL)
3322 
3323 // append lists
3324 void **listAppend(void ***list1, void **list2) MUST_CHECK;
3325 
3326 // add lists
3327 void **listAdd(void **list1, void **list2) MUST_CHECK;
3328 
3329 // slice - python style indexes 0..len-1 -1..-len+1
3330 void **listSlice(void **list, int64_t start, int64_t end) MUST_CHECK;
3331 void **iListSlice(void ***list, int64_t start, int64_t end) MUST_CHECK;
3332 
3333 // insert list in list
3334 void **listInsert(void **list, int64_t index, void **toInsert) MUST_CHECK;
3335 void **iListInsert(void ***list, int64_t index, void **toInsert) MUST_CHECK;
3336 
3337 // del - python style indexes 0..len-1 -1..-len+1
3338 void **listDel(void **list, int64_t start, int64_t end) MUST_CHECK;
3339 void **iListDel(void ***list, int64_t start, int64_t end) MUST_CHECK;
3340 //NOT NEEDED same as iListDel - void **iListRemove(void ***list, int64_t start, int64_t end);
3341 
3342 // duplicate and sort
3343 //TODO void **listSort(void **list);
3344 //TODO void iListSort(void ***list);
3345 
3346 // compare lists
3347 //TODO bool listEq(void **list1, void **list2);
3348 
3349 // indexOf
3350 //TODO ssize_t listIndexOf(void **list, const void *string);
3351 
3352 // list binary search string
3353 //TODO ssize_t listBinarySearch(void **list, const void *string);
3354 
3355 // duplicate and uniquify
3356 //TODO void **listUniq(void **list);
3357 //TODO void iListUniq(void ***list);
3358 
3359 // duplicate and compact
3360 //TODO void **listCompact(void **list);
3361 //TODO void iListCompact(void ***list);
3362 
3363 // create name variable and allocate it on heap
3364 #define newPtr(name, type)\
3365  ;type *name = malloc(sizeof(type))
3366 
3367 // create name variable and calloc it on heap
3368 #define new0Ptr(name, type)\
3369  ;type *name = calloc(1, sizeof(type))
3370 
3371 // allocate struct on heap and assign address
3372 #define allocAPtr(name) name = malloc(sizeof(*(name)))
3373 
3374 // calloc struct on heap and assign address
3375 #define callocAPtr(name) name = calloc(1, sizeof(*(name)))
3376 
3377 // create name variable and allocate array of type on heap
3378 #define newArray(name, type, count)\
3379  ;type *name = malloc((count) * sizeof(type))
3380 
3381 // create name variable and calloc array of type on heap
3382 #define new0Array(name, type, count)\
3383  ;type *name = calloc(count, sizeof(type))
3384 
3385 // allocate array
3386 #define allocArray(name, count) malloc((count) * sizeof(*(name)))
3387 
3388 // allocate and assign array
3389 #define allocAArray(name, count) name = malloc((count) * sizeof(*(name)))
3390 
3391 // calloc array
3392 #define callocArray(name, count) calloc(count, sizeof(*(name)))
3393 
3394 // calloc and assign array
3395 #define callocAArray(name, count) name = calloc(count, sizeof(*(name)))
3396 
3397 // realloc array
3398 #define reallocArray(name, count) realloc(name, (count) * sizeof(*(name)))
3399 
3445 #define sliceSz 1
3446 
3455 #define sliceT(typeName, elementType)\
3456  typedef struct {\
3457  size_t count;\
3458  elementType *array;\
3459  } typeName
3460 
3461 #define createSlice(typeName, name) ;typeName name; sliceInit(&name)
3462 
3463 #define createSliceCount(typeName, name, count) ;typeName name; sliceInitCount(&name, count)
3464 
3465 #define createSliceClearCount(typeName, name, count) ;typeName name; sliceCalloc(&name, count)
3466 
3467 #define createAllocateSlice(typeName, name) ;typeName *name = calloc(1, sizeof(typeName))
3468 
3469 #define createAllocateSliceCount(typeName, name, count) ;typeName *name = calloc(1, sizeof(typeName)); sliceInitCount(name, count)
3470 
3471 #define createAllocateSliceClearCount(typeName, name, count) ;typeName *name = calloc(1, sizeof(typeName)); sliceCalloc(name, count)
3472 
3473 #define sliceTerminate(name) if (name) sliceFree(name);free(name)
3474 
3481 #define sliceInit(name) do{\
3482  (name)->array = NULL;\
3483  (name)->count = 0;\
3484  } while(0)
3485 
3494 #define sliceInitCount(name, countInt) do{\
3495  var UNIQVAR(c) = countInt;\
3496  /* TODO check if countInt is 0 then +1 */\
3497  (name)->array = malloc(UNIQVAR(c) * sizeof (name)->array[0]);\
3498  (name)->count = 0;\
3499  } while(0)
3500 
3509 #define sliceCalloc(name, countInt) do{\
3510  var UNIQVAR(c) = countInt;\
3511  (name)->array = calloc(UNIQVAR(c), sizeof (name)->array[0]);\
3512  (name)->count = 0;\
3513  } while(0)
3514 
3518 #define sliceResize(name, countInt) do{\
3519  var UNIQVAR(c) = countInt;\
3520  if ((name)->array) {\
3521  /* realloc */\
3522  (name)->array = realloc((name)->array, sizeof((name)->array[0]) * UNIQVAR(c));\
3523  }\
3524  else {\
3525  /* was empty */\
3526  (name)->array = malloc(sizeof((name)->array[0]) * UNIQVAR(c));\
3527  }\
3528  /* element count when shrinking */\
3529  if (UNIQVAR(c) < (name)->count) (name)->count = UNIQVAR(c);\
3530  } while(0)
3531 
3536 #define sliceClearResize(name, countInt) do{\
3537  var UNIQVAR(c) = countInt;\
3538  if ((name)->array) {\
3539  /* realloc */\
3540  (name)->array = realloc((name)->array, sizeof((name)->array[0]) * UNIQVAR(c));\
3541  if ((name)->count < UNIQVAR(c)) {\
3542  /* there are new elements */\
3543  memset(&(name)->array[(name)->count], 0, (UNIQVAR(c) - (name)->count) * sizeof (name)->array[0]);\
3544  }\
3545  }\
3546  else {\
3547  /* was empty */\
3548  (name)->array = calloc(UNIQVAR(c), sizeof((name)->array[0]));\
3549  }\
3550  /* element count when shrinking */\
3551  if (UNIQVAR(c) < (name)->count) (name)->count = UNIQVAR(c);\
3552  } while(0)
3553 
3560 #define sliceFree(name) free((name)->array)
3561 
3565 #define sliceElemType(name) typeof((name)->array[0])
3566 
3570 #define sliceElemPtrType(name) typeof(&(name)->array[0])
3571 
3575 #define sliceDup(name) ({\
3576  typeof(*(name)) dest;\
3577  sliceInitCount(&dest, (name)->count);\
3578  if ((name)->array) {\
3579  memcpy(dest.array, (name)->array, (name)->count * sizeof (name)->array[0]);\
3580  dest.count = (name)->count;\
3581  }\
3582  /* return */ dest;\
3583  })
3584 
3593 /* #define sliceAgn(to, from) do{\
3594  (to)->count = (from)->count;\
3595  (to)->array = (from)->array;\
3596  } while(0) */
3597 
3601 #define sliceCreateNDup(name, dest) ;typeof(*(name)) dest; sliceInitCount(&dest, (name)->count); if ((name)->array) { memcpy(dest.array, (name)->array, (name)->count * sizeof (name)->array[0]); dest.count = (name)->count;}
3602 
3606 #define sliceBDup(name, dest) do{\
3607  var UNIQVAR(dst) = dest;\
3608  sliceResize(UNIQVAR(dst), (name)->count);\
3609  if ((name)->array) {\
3610  memcpy(UNIQVAR(dst)->array, (name)->array, (name)->count * sizeof (name)->array[0]);\
3611  UNIQVAR(dst)->count = (name)->count;\
3612  }\
3613  } while(0)
3614 
3615 
3619 #define sliceData(name) (name)->array
3620 
3624 #define sliceFrom(name, array, countInt) do{\
3625  var UNIQVAR(c) = countInt;\
3626  var UNIQVAR(a) = array;\
3627  if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
3628  sliceResize(name, UNIQVAR(c));\
3629  memcpy((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof UNIQVAR(a)[0]);\
3630  (name)->count = UNIQVAR(c);\
3631  }\
3632  } while(0)
3633 
3638 #define sliceMirror(name, start, end) ({\
3639  var UNIQVAR(strt) = start;\
3640  typeof(*(name)) UNIQVAR(r);\
3641  UNIQVAR(r).array = slicePtr(name, UNIQVAR(strt));\
3642  UNIQVAR(r).count = end - UNIQVAR(strt);\
3643  UNIQVAR(r);\
3644  })
3645 
3653 #define sliceBMirror(name, dest, start, end) do{\
3654  var UNIQVAR(strt) = start;\
3655  var UNIQVAR(dst) = dest;\
3656  UNIQVAR(dst)->array = slicePtr(name, UNIQVAR(strt));\
3657  UNIQVAR(dst)->count = end - UNIQVAR(strt);\
3658  } while(0)
3659 
3664 #define sliceMirrorFrom(name, array, countInt) do{\
3665  var UNIQVAR(strt) = start;\
3666  (name)->array = array;\
3667  (name)->count = countInt;\
3668  } while(0)
3669 
3670 
3675 #define sliceClear(name) do{\
3676  if ((name)->array)\
3677  memset((name)->array, 0, (name)->count * sizeof (name)->array[0]);\
3678  } while(0)
3679 
3680 #define sliceClearRange(name, start, end) do{\
3681  if ((name)->array)\
3682  memset((name)->array + start, 0, (end-start) * sizeof (name)->array[0]);\
3683  } while(0)
3684 
3690 #define sliceEmpty(name) (name)->count = 0
3691 
3695 #define sliceIsEmpty(name) ((name)->count == 0 || !(name)->array)
3696 
3700 #define sliceFit(name) do{\
3701  sliceResize(name, (name)->count);\
3702  } while(0)
3703 
3707 #define sliceCount(name) (name)->count
3708 
3712 #define sliceElemSize(name) sizeof((name)->array[0])
3713 
3718 #define sliceAlloc(name) do{\
3719  if (!(name)->array) {\
3720  (name)->array = malloc(sliceSz * sizeof (name)->array[0]);\
3721  }\
3722  else {\
3723  (name)->array = realloc((name)->array, ((name)->count + sliceSz) * sizeof (name)->array[0]);\
3724  }\
3725  } while(0)
3726 
3730 #define sliceClearElem(name, index) memset(&(name)->array[index], 0, sizeof (name)->array[0])
3731 
3739 #define slicePush(name) do {\
3740  sliceAlloc(name);\
3741  (name)->count++;\
3742  } while(0)
3743 
3752 #define sliceAppend(name, v) do{\
3753  slicePush(name);\
3754  sliceLast(name) = v;\
3755  } while(0)
3756 
3757 
3765 #define sliceClearPush(name) do{\
3766  slicePush(name);\
3767  sliceClearElem(name, (name)->count - 1);\
3768  } while(0)
3769 
3781 #define slicePop(name) ((name)->count--, (name)->array[(name)->count])
3782 
3788 #define sliceDelLast(name) ((name)->count--)
3789 
3793 #define sliceSet(name, index, v) do{\
3794  var UNIQVAR(idx) = index;\
3795  if (UNIQVAR(idx) >= (name)->count) {\
3796  /* clear and resize */\
3797  sliceClearResize(name, UNIQVAR(idx)+1);\
3798  }\
3799  sliceAt(name, UNIQVAR(idx)) = v;\
3800  } while(0)
3801 
3810 #define sliceAt(name, index) ((name)->array[index])
3811 
3820 #define slicePtr(name, index) ((name)->array + index)
3821 
3828 #define sliceLast(name) ((name)->array[(name)->count-1])
3829 
3836 #define sliceLastPtr(name) ((name)->array + (name)->count - 1)
3837 
3841 #define sliceLastIndex(name) ((name)->count - 1)
3842 
3843 
3850 #define sliceFirst(name) ((name)->array[0])
3851 
3852 
3860 #define sliceWriteFilename(name, filename) do {\
3861  FILE *UNIQVAR(f) = fopen(filename, "w");\
3862  if (UNIQVAR(f)) {\
3863  fwrite((name)->array, sizeof((name)->array[0]), sliceCount(name), UNIQVAR(f));\
3864  fclose(UNIQVAR(f));\
3865  }\
3866  } while(0)
3867 
3875 #define sliceWrite(name, file) fwrite((name)->array, sizeof((name)->array[0]), sliceCount(name), file)
3876 
3884 #define sliceReadFilename(name, filename) do {\
3885  if (fileExists(filename)) {\
3886  size_t UNIQVAR(sz) = fileSize(filename);\
3887  FILE *UNIQVAR(f) = fopen(filename, "r");\
3888  if (UNIQVAR(f)) {\
3889  range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
3890  slicePush(name);\
3891  fread(sliceLastPtr(name), 1, sizeof((name)->array[0]), UNIQVAR(f));\
3892  }\
3893  fclose(UNIQVAR(f));\
3894  }\
3895  }\
3896  } while(0)
3897 
3905 #define sliceRead(name, file) do {\
3906  fseek(file, 0 , SEEK_END);\
3907  size_t UNIQVAR(sz) = ftell(file);\
3908  fseek(file, 0 , SEEK_SET);\
3909  range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
3910  slicePush(name);\
3911  fread(sliceLastPtr(name), 1, sizeof((name)->array[0]), file);\
3912  }\
3913  } while(0)
3914 
3915 
3924 #define forEachSc(name, index) range(index, (name)->count)
3925 
3934 #define sliceForEach(name, element) \
3935  ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
3936  for (sliceElemPtrType(name) element = slicePtr(name, 0) ; UNIQVAR(libsheepyInternalIndex) < (name)->count ; UNIQVAR(libsheepyInternalIndex)++, element = slicePtr(name, UNIQVAR(libsheepyInternalIndex)))
3937 
3949 #define sliceEnumerate(name, index, element) \
3950  ; size_t index = 0 ; \
3951  for (sliceElemPtrType(name) element = slicePtr(name, 0) ; index < (name)->count ; index++, element = slicePtr(name, index))
3952 
3958 #define sliceInject(name, index) do {\
3959  var UNIQVAR(idx) = index;\
3960  slicePush(name);\
3961  if (index < sliceCount(name)) {\
3962  memmove(slicePtr(name, UNIQVAR(idx) +1), slicePtr(name, UNIQVAR(idx)), ((name)->count - UNIQVAR(idx)-1) * sizeof (name)->array[0]);\
3963  }\
3964  } while(0)
3965 
3974 #define slicePrepend(name, v) do {\
3975  sliceInject(name, 0);\
3976  sliceAt(name, 0) = v;\
3977  } while(0)
3978 
3985 #define sliceDequeue(name) ({\
3986  var r = sliceAt(name, 0);\
3987  sliceDelFirst(name);\
3988  /* return */r;\
3989  })
3990 
3995 #define sliceDelFirst(name) do {\
3996  if ((name)->count) {\
3997  if ((name)->count > 1) {\
3998  /* move elements */\
3999  memcpy((name)->array, (name)->array +1 , ((name)->count - 1) * sizeof (name)->array[0]);\
4000  }\
4001  (name)->count--;\
4002  }\
4003  } while(0)
4004 
4005 
4011 #define sliceDelElem(name, index) do {\
4012  var UNIQVAR(idx) = index;\
4013  if ((size_t)UNIQVAR(idx) < (size_t)sliceLastIndex(name)) {\
4014  /* move elements */\
4015  memmove(slicePtr(name, UNIQVAR(idx)), slicePtr(name, UNIQVAR(idx) +1), ((name)->count - (UNIQVAR(idx) +1)) * sizeof (name)->array[0]);\
4016  }\
4017  (name)->count--;\
4018  } while(0)
4019 
4025 #define sliceDel(name, start, end) do {\
4026  var UNIQVAR(strt) = start;\
4027  var UNIQVAR(ed) = end;\
4028  if (UNIQVAR(ed) < (name)->count and UNIQVAR(strt) < UNIQVAR(ed)) {\
4029  /* move elements */\
4030  memmove(slicePtr(name, UNIQVAR(strt)), slicePtr(name, UNIQVAR(ed)), ((name)->count - UNIQVAR(ed)) * sizeof (name)->array[0]);\
4031  }\
4032  (name)->count -= UNIQVAR(ed) - UNIQVAR(strt);\
4033  } while(0)
4034 
4039 #define sliceVAppend(name, slice) do {\
4040  var UNIQVAR(vec) = slice;\
4041  if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
4042  sliceResize(name, (name)->count + (UNIQVAR(vec))->count);\
4043  memmove((name)->array + (name)->count, (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
4044  (name)->count += (UNIQVAR(vec))->count;\
4045  }\
4046  } while(0)
4047 
4052 #define sliceAppendFrom(name, array, countInt) do {\
4053  var UNIQVAR(c) = countInt;\
4054  var UNIQVAR(a) = array;\
4055  if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
4056  sliceResize(name, (name)->count + UNIQVAR(c));\
4057  memmove((name)->array + (name)->count, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
4058  (name)->count += UNIQVAR(c);\
4059  }\
4060  } while(0)
4061 
4067 #define sliceVPrepend(name, slice) do {\
4068  var UNIQVAR(vec) = slice;\
4069  if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
4070  sliceResize(name, (name)->count + (UNIQVAR(vec))->count);\
4071  memmove((name)->array + (UNIQVAR(vec))->count, (name)->array, (name)->count * sizeof (name)->array[0]);\
4072  memmove((name)->array, (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
4073  (name)->count += (UNIQVAR(vec))->count;\
4074  }\
4075  } while(0)
4076 
4082 #define slicePrependFrom(name, array, countInt) do {\
4083  var UNIQVAR(c) = countInt;\
4084  var UNIQVAR(a) = array;\
4085  if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
4086  sliceResize(name, (name)->count + UNIQVAR(c));\
4087  memmove((name)->array + UNIQVAR(c), (name)->array, (name)->count * sizeof (name)->array[0]);\
4088  memmove((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
4089  (name)->count += UNIQVAR(c);\
4090  }\
4091  } while(0);
4092 
4098 #define sliceInsert(name, index, slice) do {\
4099  var UNIQVAR(idx) = index;\
4100  var UNIQVAR(vec) = slice;\
4101  if (UNIQVAR(idx) == (name)->count) {\
4102  sliceAppend(name, UNIQVAR(vec));\
4103  }\
4104  else if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
4105  sliceResize(name, (name)->count + (UNIQVAR(vec))->count);\
4106  memmove((name)->array + UNIQVAR(idx) + (UNIQVAR(vec))->count, (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
4107  memmove((name)->array + UNIQVAR(idx), (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
4108  (name)->count += (UNIQVAR(vec))->count;\
4109  }\
4110  } while(0)
4111 
4117 #define sliceInsertFrom(name, index, array, countInt) do {\
4118  var UNIQVAR(idx) = index;\
4119  var UNIQVAR(c) = countInt;\
4120  var UNIQVAR(a) = array;\
4121  if (UNIQVAR(idx) == (name)->count) {\
4122  sliceAppendFrom(name, UNIQVAR(a), UNIQVAR(c));\
4123  }\
4124  else if (sizeof((name)->array[0]) == sizeof(UNIQVAR(a)[0])) {\
4125  sliceResize(name, (name)->count + UNIQVAR(c));\
4126  memmove((name)->array + UNIQVAR(idx) + UNIQVAR(c), (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
4127  memmove((name)->array + UNIQVAR(idx), UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
4128  (name)->count += UNIQVAR(c);\
4129  }\
4130  } while(0)
4131 
4138 #define sliceSlice(name, start, end) ({\
4139  var UNIQVAR(strt) = start;\
4140  var UNIQVAR(ed) = end;\
4141  if (UNIQVAR(strt))\
4142  memmove((name)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
4143  (name)->count = UNIQVAR(ed) - UNIQVAR(strt);\
4144  name;\
4145  })
4146 
4153 #define sliceCopy(name, start, end) ({\
4154  var UNIQVAR(strt) = start;\
4155  var UNIQVAR(ed) = end;\
4156  createAllocateSliceCount(typeof(*(name)),UNIQVAR(r), UNIQVAR(ed) - UNIQVAR(strt));\
4157  memmove(UNIQVAR(r)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
4158  UNIQVAR(r)->count = UNIQVAR(ed) - UNIQVAR(strt);\
4159  UNIQVAR(r);\
4160  })
4161 
4167 #define sliceBCopy(name, dest, start, end) do{\
4168  if (sizeof((name)->array[0]) == sizeof((dest)->array[0])) {\
4169  var UNIQVAR(strt) = start;\
4170  var UNIQVAR(ed) = end;\
4171  sliceResize(dest, UNIQVAR(ed) - UNIQVAR(strt));\
4172  memmove((dest)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
4173  (dest)->count = UNIQVAR(ed) - UNIQVAR(strt);\
4174  }\
4175  } while(0)
4176 
4186 #define sliceSort(name, compareFunction) do{ \
4187  qsort((name)->array, sizeof (name)->array[0], compareFunction);\
4188  } while(0)
4189 
4195 #define sliceEq(name, slice, eqFunction) ({\
4196  var UNIQVAR(vec) = slice;\
4197  bool UNIQVAR(r) = true;\
4198  if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0]) and (name)->count == UNIQVAR(vec)->count) {\
4199  forEachV(name, UNIQVAR(idx)) {\
4200  if (not eqFunction(sliceAt(name,UNIQVAR(idx)), sliceAt(UNIQVAR(vec),UNIQVAR(idx)))) {\
4201  UNIQVAR(r) = false;\
4202  break;\
4203  }\
4204  }\
4205  }\
4206  else UNIQVAR(r) = false;\
4207  UNIQVAR(r);\
4208  })
4209 
4215 #define sliceHas(name, value, eqFunction) ({\
4216  var UNIQVAR(v) = value;\
4217  bool UNIQVAR(r) = false;\
4218  forEachV(name, UNIQVAR(idx)) {\
4219  if (eqFunction(sliceAt(name,UNIQVAR(idx)), UNIQVAR(v))) {\
4220  UNIQVAR(r) = true;\
4221  break;\
4222  }\
4223  }\
4224  UNIQVAR(r);\
4225  })
4226 
4234 #define sliceIndexOf(name, value, eqFunction) ({\
4235  var UNIQVAR(v) = value;\
4236  ssize_t UNIQVAR(r) = -1;\
4237  forEachV(name, UNIQVAR(idx)) {\
4238  if (eqFunction(sliceAt(name,UNIQVAR(idx)), UNIQVAR(v))) {\
4239  UNIQVAR(r) = UNIQVAR(idx);\
4240  break;\
4241  }\
4242  }\
4243  UNIQVAR(r);\
4244  })
4245 
4260 #define sliceBinarySearch(name, value, less, equal) ({\
4261  var UNIQVAR(v) = value;\
4262  ssize_t UNIQVAR(r);\
4263  BSEARCH(UNIQVAR(r), UNIQVAR(v), (name)->count, less, equal);\
4264  UNIQVAR(r);\
4265  })
4266 
4274 #define sliceUniq(name, eqFunction) do{\
4275  if ((name)->count > 1) {\
4276  /* more than 1 element in slice, it is possible to have non unique elements */\
4277  /* where to copy unique elements */\
4278  size_t UNIQVAR(addIdx) = 0;\
4279  /* scan all elements */\
4280  forEachV(name, UNIQVAR(idx)) {\
4281  /* whether [idx+1, count] has an element equal the one at idx */\
4282  bool UNIQVAR(has) = false;\
4283  /* last element is always unique */\
4284  if (UNIQVAR(idx) < (name)->count) {\
4285  rangeFrom(UNIQVAR(i), UNIQVAR(idx)+1, (name)->count) {\
4286  if (eqFunction(sliceAt(name,UNIQVAR(i)), sliceAt(name,UNIQVAR(idx)))) {\
4287  UNIQVAR(r) = true;\
4288  break;\
4289  }\
4290  }\
4291  }\
4292  /* if [idx+1, count] doesnt have an equal element then the element at idx is unique */\
4293  if (not UNIQVAR(has)) {\
4294  /* copy element to addIdx when addIdx < idx */\
4295  /* when addIdx == idx there is no need to copy the element */\
4296  if (UNIQVAR(addIdx) < UNIQVAR(idx)) {\
4297  sliceAt(name,UNIQVAR(addIdx)) = sliceAt(name,UNIQVAR(idx));\
4298  }\
4299  UNIQVAR(addIdx)++;\
4300  }\
4301  }\
4302  /* set new count */\
4303  (name)->count = UNIQVAR(addIdx);\
4304  }\
4305  } while(0)
4306 
4307 /*
4308  * end slice
4309  */
4310 
4360 #define staticSliceT(typeName, elementType, MAXCOUNT)\
4361  typedef struct {\
4362  size_t count;\
4363  elementType array[MAXCOUNT];\
4364  } typeName
4365 
4366 #define createStaticSlice(typeName, name) ;typeName name; staticSliceInit(&name)
4367 
4374 #define staticSliceInit(name) do{\
4375  (name)->count = 0;\
4376  } while(0)
4377 
4381 #define staticSliceElemType(name) typeof((name)->array[0])
4382 
4386 #define staticSliceElemPtrType(name) typeof(&(name)->array[0])
4387 
4391 #define staticSliceBDup(name, dest) do{\
4392  var UNIQVAR(dst) = dest;\
4393  if ((name)->count <= ARRAY_SIZE(UNIQVAR(dst)->array)) {\
4394  memcpy(UNIQVAR(dst)->array, (name)->array, (name)->count * sizeof (name)->array[0]);\
4395  UNIQVAR(dst)->count = (name)->count;\
4396  }\
4397  } while(0)
4398 
4399 
4403 #define staticSliceData sliceData
4404 
4408 #define staticSliceFrom(name, array, countInt) do{\
4409  var UNIQVAR(c) = countInt;\
4410  var UNIQVAR(a) = array;\
4411  if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a))) /* slice compatibility and UNIQVAR(c) <= ARRAY_SIZE((name)->array)*/) {\
4412  memcpy((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof UNIQVAR(a)[0]);\
4413  (name)->count = UNIQVAR(c);\
4414  }\
4415  } while(0)
4416 
4417 
4422 #define staticSliceClear(name) memset((name)->array, 0, (name)->count * sizeof (name)->array[0])
4423 
4424 #define staticSliceClearRange(name, start, end) memset((name)->array + start, 0, (end-start) * sizeof (name)->array[0])
4425 
4431 #define staticSliceEmpty sliceEmpty
4432 
4436 #define staticSliceIsEmpty(name) ((name)->count == 0)
4437 
4441 #define staticSliceCount sliceCount
4442 
4446 #define staticSliceElemSize sliceElemSize
4447 
4451 #define staticSliceClearElem sliceClearElem
4452 
4460 #define staticSlicePush(name) (name)->count++
4461 
4470 #define staticSliceAppend(name, v) do{\
4471  staticSlicePush(name);\
4472  staticSliceLast(name) = v;\
4473  } while(0)
4474 
4475 
4483 #define staticSliceClearPush(name) do{\
4484  staticSlicePush(name);\
4485  staticSliceClearElem(name, (name)->count - 1);\
4486  } while(0)
4487 
4499 #define staticSlicePop slicePop
4500 
4506 #define staticSliceDelLast sliceDelLast
4507 
4516 #define staticSliceAt sliceAt
4517 
4526 #define staticSlicePtr slicePtr
4527 
4534 #define staticSliceLast sliceLast
4535 
4542 #define staticSliceLastPtr sliceLastPtr
4543 
4547 #define staticSliceLastIndex sliceLastIndex
4548 
4549 
4556 #define staticSliceFirst sliceFirst
4557 
4558 
4566 #define staticSliceWriteFilename sliceWriteFilename
4567 
4575 #define staticSliceWrite sliceWrite
4576 
4584 #define staticSliceReadFilename(name, filename) do {\
4585  if (fileExists(filename)) {\
4586  size_t UNIQVAR(sz) = fileSize(filename);\
4587  FILE *UNIQVAR(f) = fopen(filename, "r");\
4588  if (UNIQVAR(f)) {\
4589  range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
4590  staticSlicePush(name);\
4591  fread(staticSliceLastPtr(name), 1, sizeof((name)->array[0]), UNIQVAR(f));\
4592  }\
4593  fclose(UNIQVAR(f));\
4594  }\
4595  }\
4596  } while(0)
4597 
4605 #define staticSliceRead(name, file) do {\
4606  fseek(file, 0 , SEEK_END);\
4607  size_t UNIQVAR(sz) = ftell(file);\
4608  fseek(file, 0 , SEEK_SET);\
4609  range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
4610  staticSlicePush(name);\
4611  fread(staticSliceLastPtr(name), 1, sizeof((name)->array[0]), file);\
4612  }\
4613  } while(0)
4614 
4615 
4624 #define forEachSSc forEachSc
4625 
4634 #define staticSliceForEach(name, element) \
4635  ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
4636  for (staticSliceElemPtrType(name) element = staticSlicePtr(name, 0) ; UNIQVAR(libsheepyInternalIndex) < (name)->count ; UNIQVAR(libsheepyInternalIndex)++, element = staticSlicePtr(name, UNIQVAR(libsheepyInternalIndex)))
4637 
4649 #define staticSliceEnumerate(name, index, element) \
4650  ; size_t index = 0 ; \
4651  for (staticSliceElemPtrType(name) element = staticSlicePtr(name, 0) ; index < (name)->count ; index++, element = staticSlicePtr(name, index))
4652 
4658 #define staticSliceInject(name, index) do {\
4659  var UNIQVAR(idx) = index;\
4660  staticSlicePush(name);\
4661  memmove(staticSlicePtr(name, UNIQVAR(idx) +1), staticSlicePtr(name, UNIQVAR(idx)), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
4662  } while(0)
4663 
4672 #define staticSlicePrepend(name, v) do {\
4673  staticSliceInject(name, 0);\
4674  staticSliceAt(name, 0) = v;\
4675  } while(0)
4676 
4683 #define staticSliceDequeue sliceDequeue
4684 
4689 #define staticSliceDelFirst sliceDelFirst
4690 
4691 
4697 #define staticSliceDelElem sliceDelElem
4698 
4704 #define staticSliceDel sliceDel
4705 
4710 #define staticSliceVAppend(name, staticSlice) do {\
4711  var UNIQVAR(vec) = staticSlice;\
4712  if (sizeof((name)->array[0]) == sizeof(UNIQVAR(vec)->array[0]) /* slice compatibility and ((name)->count + UNIQVAR(vec)->count) <= ARRAY_SIZE((name)->array)*/) {\
4713  memcpy((name)->array + (name)->count, UNIQVAR(vec)->array, UNIQVAR(vec)->count * sizeof (name)->array[0]);\
4714  (name)->count += UNIQVAR(vec)->count;\
4715  }\
4716  } while(0)
4717 
4722 #define staticSliceAppendFrom(name, array, countInt) do {\
4723  var UNIQVAR(c) = countInt;\
4724  var UNIQVAR(a) = array;\
4725  if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a))) /* slice compatibility and ((name)->count + UNIQVAR(c)) <= ARRAY_SIZE((name)->array)*/) {\
4726  memcpy((name)->array + (name)->count, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
4727  (name)->count += UNIQVAR(c);\
4728  }\
4729  } while(0)
4730 
4736 #define staticSliceVPrepend(name, staticSlice) do {\
4737  var UNIQVAR(vec) = staticSlice;\
4738  if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0]) /* slice compatibility and ((name)->count + UNIQVAR(vec)->count) <= ARRAY_SIZE((name)->array)*/) {\
4739  memmove((name)->array + (UNIQVAR(vec))->count, (name)->array, (name)->count * sizeof (name)->array[0]);\
4740  memcpy((name)->array, (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
4741  (name)->count += (UNIQVAR(vec))->count;\
4742  }\
4743  } while(0)
4744 
4750 #define staticSlicePrependFrom(name, array, countInt) do {\
4751  var UNIQVAR(c) = countInt;\
4752  var UNIQVAR(a) = array;\
4753  if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a))) /* slice compatibility and ((name)->count + UNIQVAR(c)) <= ARRAY_SIZE((name)->array)*/) {\
4754  staticSliceResize(name, (name)->count + UNIQVAR(c));\
4755  memmove((name)->array + UNIQVAR(c), (name)->array, (name)->count * sizeof (name)->array[0]);\
4756  memcpy((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
4757  (name)->count += UNIQVAR(c);\
4758  }\
4759  } while(0);
4760 
4766 #define staticSliceInsert(name, index, staticSlice) do {\
4767  var UNIQVAR(idx) = index;\
4768  var UNIQVAR(vec) = staticSlice;\
4769  if (UNIQVAR(idx) == (name)->count) {\
4770  staticSliceAppend(name, UNIQVAR(vec));\
4771  }\
4772  else if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0]) /* slice compatibility and ((name)->count + UNIQVAR(vec)->count) <= ARRAY_SIZE((name)->array)*/) {\
4773  memmove((name)->array + UNIQVAR(idx) + (UNIQVAR(vec))->count, (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
4774  memcpy((name)->array + UNIQVAR(idx), (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
4775  (name)->count += (UNIQVAR(vec))->count;\
4776  }\
4777  } while(0)
4778 
4784 #define staticSliceInsertFrom(name, index, array, countInt) do {\
4785  var UNIQVAR(idx) = index;\
4786  var UNIQVAR(c) = countInt;\
4787  var UNIQVAR(a) = array;\
4788  if (UNIQVAR(idx) == (name)->count) {\
4789  staticSliceAppendFrom(name, UNIQVAR(a), UNIQVAR(c));\
4790  }\
4791  else if (sizeof((name)->array[0]) == sizeof(UNIQVAR(a)[0]) /* slice compatibility and ((name)->count + UNIQVAR(c)) <= ARRAY_SIZE((name)->array)*/) {\
4792  memmove((name)->array + UNIQVAR(idx) + UNIQVAR(c), (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
4793  memcpy((name)->array + UNIQVAR(idx), UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
4794  (name)->count += UNIQVAR(c);\
4795  }\
4796  } while(0)
4797 
4804 #define staticSliceSlice sliceSlice
4805 
4811 #define staticSliceBCopy(name, dest, start, end) do{\
4812  if (sizeof((name)->array[0]) == sizeof((dest)->array[0]) /* slice compatibility and (UNIQVAR(ed) - UNIQVAR(strt)) <= ARRAY_SIZE((dest)->array)*/) {\
4813  var UNIQVAR(strt) = start;\
4814  var UNIQVAR(ed) = end;\
4815  staticSliceResize(dest, UNIQVAR(ed) - UNIQVAR(strt));\
4816  memcpy((dest)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
4817  (dest)->count = UNIQVAR(ed) - UNIQVAR(strt);\
4818  }\
4819  } while(0)
4820 
4830 #define staticSliceSort sliceSort
4831 
4837 #define staticSliceEq sliceEq
4838 
4844 #define staticSliceHas sliceHas
4845 
4853 #define staticSliceIndexOf sliceIndexOf
4854 
4869 #define staticSliceBinarySearch sliceBinarySearch
4870 
4878 #define staticSliceUniq sliceUniq
4879 
4880 /*
4881  * end staticSlice
4882  */
4883 
4932 #define vectorSz 1
4933 
4942 #define vectorT(typeName, elementType)\
4943  typedef struct {\
4944  size_t count;\
4945  size_t maxCount;\
4946  elementType *array;\
4947  } typeName
4948 
4949 
4950 #define createVector(typeName, name) ;typeName name; vectorInit(&name)
4951 
4952 #define createVectorCount(typeName, name, count) ;typeName name; vectorInitCount(&name, count)
4953 
4954 #define createVectorClearCount(typeName, name, count) ;typeName name; vectorCalloc(&name, count)
4955 
4956 #define createAllocateVector(typeName, name) ;typeName *name = calloc(1, sizeof(typeName))
4957 
4958 #define createAllocateVectorCount(typeName, name, count) ;typeName *name = calloc(1, sizeof(typeName)); vectorInitCount(name, count)
4959 
4960 #define createAllocateVectorClearCount(typeName, name, count) ;typeName *name = calloc(1, sizeof(typeName)); vectorCalloc(name, count)
4961 
4962 #define vectorTerminate(name) if (name) vectorFree(name);free(name)
4963 
4970 #define vectorInit(name) do{\
4971  (name)->array = NULL;\
4972  (name)->count = 0;\
4973  (name)->maxCount = 0;\
4974  } while(0)
4975 
4984 #define vectorInitCount(name, countInt) do{\
4985  var UNIQVAR(c) = countInt;\
4986  (name)->array = malloc(UNIQVAR(c) * sizeof (name)->array[0]);\
4987  (name)->count = 0;\
4988  (name)->maxCount = UNIQVAR(c);\
4989  } while(0)
4990 
4999 #define vectorCalloc(name, countInt) do{\
5000  var UNIQVAR(c) = countInt;\
5001  (name)->array = calloc(UNIQVAR(c), sizeof (name)->array[0]);\
5002  (name)->count = 0;\
5003  (name)->maxCount = UNIQVAR(c);\
5004  } while(0)
5005 
5009 #define vectorResize(name, countInt) do{\
5010  var UNIQVAR(c) = countInt;\
5011  if ((name)->array) {\
5012  /* realloc */\
5013  (name)->array = realloc((name)->array, sizeof((name)->array[0]) * UNIQVAR(c));\
5014  }\
5015  else {\
5016  /* was empty */\
5017  (name)->array = malloc(sizeof((name)->array[0]) * UNIQVAR(c));\
5018  }\
5019  /* element count when shrinking */\
5020  if (UNIQVAR(c) < (name)->count) (name)->count = UNIQVAR(c);\
5021  (name)->maxCount = UNIQVAR(c);\
5022  } while(0)
5023 
5028 #define vectorClearResize(name, countInt) do{\
5029  var UNIQVAR(c) = countInt;\
5030  if ((name)->array) {\
5031  /* realloc */\
5032  (name)->array = realloc((name)->array, sizeof((name)->array[0]) * UNIQVAR(c));\
5033  if ((name)->count < UNIQVAR(c)) {\
5034  /* there are new elements */\
5035  memset(&(name)->array[(name)->count], 0, (UNIQVAR(c) - (name)->count) * sizeof (name)->array[0]);\
5036  }\
5037  }\
5038  else {\
5039  /* was empty */\
5040  (name)->array = calloc(UNIQVAR(c), sizeof((name)->array[0]));\
5041  }\
5042  /* element count when shrinking */\
5043  if (UNIQVAR(c) < (name)->count) (name)->count = UNIQVAR(c);\
5044  (name)->maxCount = UNIQVAR(c);\
5045  } while(0)
5046 
5053 #define vectorFree sliceFree
5054 
5058 #define vectorElemType(name) typeof((name)->array[0])
5059 
5063 #define vectorElemPtrType(name) typeof(&(name)->array[0])
5064 
5068 #define vectorDup(name) ({\
5069  typeof(*(name)) dest;\
5070  vectorInitCount(dest, (name)->count);\
5071  if ((name)->array) {\
5072  memcpy(dest->array, (name)->array, (name)->count * sizeof (name)->array[0]);\
5073  dest->count = (name)->count;\
5074  }\
5075  /* return */ dest;\
5076  })
5077 
5080 #define vectorCreateNDup(name, dest) ;typeof(*(name)) dest; vectorInitCount(dest, (name)->count); if ((name)->array) { memcpy(dest->array, (name)->array, (name)->count * sizeof (name)->array[0]); dest->count = (name)->count;}
5081 
5085 #define vectorBDup(name, dest) do{\
5086  var UNIQVAR(dst) = dest;\
5087  vectorResize(UNIQVAR(dst), (name)->count);\
5088  if ((name)->array) {\
5089  memcpy(UNIQVAR(dst)->array, (name)->array, (name)->count * sizeof (name)->array[0]);\
5090  dest->count = (name)->count;\
5091  }\
5092  } while(0)
5093 
5097 #define vectorData sliceData
5098 
5102 #define vectorFrom(name, array, countInt) do{\
5103  var UNIQVAR(c) = countInt;\
5104  var UNIQVAR(a) = array;\
5105  if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
5106  if (UNIQVAR(c) > (name)->maxCount)\
5107  vectorResize(name, UNIQVAR(c));\
5108  memcpy((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof UNIQVAR(a)[0]);\
5109  (name)->count = UNIQVAR(c);\
5110  }\
5111  } while(0)
5112 
5117 #define vectorClear sliceClear
5118 
5119 #define vectorClearRange sliceClearRange
5120 
5126 #define vectorEmpty sliceEmpty
5127 
5131 #define vectorIsEmpty sliceIsEmpty
5132 
5136 #define vectorFit(name) do{\
5137  if ((name)->maxCount > (name)->count) {\
5138  vectorResize(name, (name)->count);\
5139  }\
5140  } while(0)
5141 
5145 #define vectorCount sliceCount
5146 
5150 #define vectorMaxCount(name) (name)->maxCount
5151 
5155 #define vectorElemSize sliceElemSize
5156 
5161 #define vectorAlloc(name) do{\
5162  if (!(name)->array) {\
5163  (name)->array = malloc(vectorSz * sizeof (name)->array[0]);\
5164  (name)->maxCount = vectorSz;\
5165  }\
5166  else if ((name)->count == (name)->maxCount) {\
5167  (name)->maxCount += vectorSz;\
5168  (name)->array = realloc((name)->array, (name)->maxCount * sizeof (name)->array[0]);\
5169  }\
5170  } while(0)
5171 
5175 #define vectorClearElem sliceClearElem
5176 
5184 #define vectorPush(name) do {\
5185  vectorAlloc(name);\
5186  (name)->count++;\
5187  } while(0)
5188 
5197 #define vectorAppend(name, v) do{\
5198  vectorPush(name);\
5199  vectorLast(name) = v;\
5200  } while(0)
5201 
5202 
5210 #define vectorClearPush(name) do{\
5211  vectorPush(name);\
5212  vectorClearElem(name, (name)->count - 1);\
5213  } while(0)
5214 
5226 #define vectorPop slicePop
5227 
5233 #define vectorDelLast sliceDelLast
5234 
5243 #define vectorPushCount(name, countp) procbegin\
5244  u32 UNIQVAR(count) = countp;\
5245  if (((name)->count + UNIQVAR(count)) > (name)->maxCount) {\
5246  (name)->maxCount += UNIQVAR(count);\
5247  (name)->array = realloc((name)->array, (name)->maxCount * sizeof (name)->array[0]);\
5248  }\
5249  (name)->count += UNIQVAR(count);\
5250  procend
5251 
5252 
5256 #define vectorSet(name, index, v) do{\
5257  var UNIQVAR(idx) = index;\
5258  if (UNIQVAR(idx) >= (name)->count) {\
5259  /* clear and resize */\
5260  vectorClearResize(name, UNIQVAR(idx)+1);\
5261  }\
5262  vectorAt(name, UNIQVAR(idx)) = v;\
5263  } while(0)
5264 
5273 #define vectorAt sliceAt
5274 
5283 #define vectorPtr slicePtr
5284 
5291 #define vectorLast sliceLast
5292 
5299 #define vectorLastPtr sliceLastPtr
5300 
5304 #define vectorLastIndex sliceLastIndex
5305 
5306 
5313 #define vectorFirst sliceFirst
5314 
5315 
5323 #define vectorWriteFilename sliceWriteFilename
5324 
5332 #define vectorWrite sliceWrite
5333 
5341 #define vectorReadFilename(name, filename) do {\
5342  if (fileExists(filename)) {\
5343  size_t UNIQVAR(sz) = fileSize(filename);\
5344  FILE *UNIQVAR(f) = fopen(filename, "r");\
5345  if (UNIQVAR(f)) {\
5346  range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
5347  vectorPush(name);\
5348  fread(vectorLastPtr(name), 1, sizeof((name)->array[0]), UNIQVAR(f));\
5349  }\
5350  fclose(UNIQVAR(f));\
5351  }\
5352  }\
5353  } while(0)
5354 
5362 #define vectorRead(name, file) do {\
5363  fseek(file, 0 , SEEK_END);\
5364  size_t UNIQVAR(sz) = ftell(file);\
5365  fseek(file, 0 , SEEK_SET);\
5366  range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
5367  vectorPush(name);\
5368  fread(vectorLastPtr(name), 1, sizeof((name)->array[0]), file);\
5369  }\
5370  } while(0)
5371 
5372 
5381 #define forEachV forEachSc
5382 
5391 #define vectorForEach(name, element) \
5392  ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
5393  for (vectorElemPtrType(name) element = vectorPtr(name, 0) ; UNIQVAR(libsheepyInternalIndex) < (name)->count ; UNIQVAR(libsheepyInternalIndex)++, element = vectorPtr(name, UNIQVAR(libsheepyInternalIndex)))
5394 
5406 #define vectorEnumerate(name, index, element) \
5407  ; size_t index = 0 ; \
5408  for (vectorElemPtrType(name) element = vectorPtr(name, 0) ; index < (name)->count ; index++, element = vectorPtr(name, index))
5409 
5415 #define vectorInject(name, index) do {\
5416  var UNIQVAR(idx) = index;\
5417  vectorPush(name);\
5418  memmove(vectorPtr(name, UNIQVAR(idx) +1), vectorPtr(name, UNIQVAR(idx)), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
5419  } while(0)
5420 
5429 #define vectorPrepend(name, v) do {\
5430  vectorInject(name, 0);\
5431  vectorAt(name, 0) = v;\
5432  } while(0)
5433 
5440 #define vectorDequeue sliceDequeue
5441 
5446 #define vectorDelFirst sliceDelFirst
5447 
5448 
5454 #define vectorDelElem sliceDelElem
5455 
5461 #define vectorDel sliceDel
5462 
5467 #define vectorVAppend(name, vector) do {\
5468  var UNIQVAR(vec) = vector;\
5469  if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
5470  if (((name)->count + (UNIQVAR(vec))->count) > (name)->maxCount)\
5471  vectorResize(name, (name)->count + (UNIQVAR(vec))->count);\
5472  memcpy((name)->array + (name)->count, (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
5473  (name)->count += (UNIQVAR(vec))->count;\
5474  }\
5475  } while(0)
5476 
5481 #define vectorAppendFrom(name, array, countInt) do {\
5482  var UNIQVAR(c) = countInt;\
5483  var UNIQVAR(a) = array;\
5484  if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
5485  if (((name)->count + UNIQVAR(c)) > (name)->maxCount)\
5486  vectorResize(name, (name)->count + UNIQVAR(c));\
5487  memcpy((name)->array + (name)->count, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
5488  (name)->count += UNIQVAR(c);\
5489  }\
5490  } while(0)
5491 
5497 #define vectorVPrepend(name, vector) do {\
5498  var UNIQVAR(vec) = vector;\
5499  if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
5500  if (((name)->count + (UNIQVAR(vec))->count) > (name)->maxCount)\
5501  vectorResize(name, (name)->count + (UNIQVAR(vec))->count);\
5502  memmove((name)->array + (UNIQVAR(vec))->count, (name)->array, (name)->count * sizeof (name)->array[0]);\
5503  memcpy((name)->array, (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
5504  (name)->count += (UNIQVAR(vec))->count;\
5505  }\
5506  } while(0)
5507 
5513 #define vectorPrependFrom(name, array, countInt) do {\
5514  var UNIQVAR(c) = countInt;\
5515  var UNIQVAR(a) = array;\
5516  if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
5517  if (((name)->count + UNIQVAR(c)) > (name)->maxCount)\
5518  vectorResize(name, (name)->count + UNIQVAR(c));\
5519  memmove((name)->array + UNIQVAR(c), (name)->array, (name)->count * sizeof (name)->array[0]);\
5520  memcpy((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
5521  (name)->count += UNIQVAR(c);\
5522  }\
5523  } while(0);
5524 
5530 #define vectorInsert(name, index, vector) do {\
5531  var UNIQVAR(idx) = index;\
5532  var UNIQVAR(vec) = vector;\
5533  if (UNIQVAR(idx) == (name)->count) {\
5534  vectorAppend(name, UNIQVAR(vec));\
5535  }\
5536  else if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
5537  if (((name)->count + (UNIQVAR(vec))->count) > (name)->maxCount)\
5538  vectorResize(name, (name)->count + (UNIQVAR(vec))->count);\
5539  memmove((name)->array + UNIQVAR(idx) + (UNIQVAR(vec))->count, (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
5540  memcpy((name)->array + UNIQVAR(idx), (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
5541  (name)->count += (UNIQVAR(vec))->count;\
5542  }\
5543  } while(0)
5544 
5550 #define vectorInsertFrom(name, index, array, countInt) do {\
5551  var UNIQVAR(idx) = index;\
5552  var UNIQVAR(c) = countInt;\
5553  var UNIQVAR(a) = array;\
5554  if (UNIQVAR(idx) == (name)->count) {\
5555  vectorAppendFrom(name, UNIQVAR(a), UNIQVAR(c));\
5556  }\
5557  else if (sizeof((name)->array[0]) == sizeof(UNIQVAR(a)[0])) {\
5558  if (((name)->count + UNIQVAR(c)) > (name)->maxCount)\
5559  vectorResize(name, (name)->count + UNIQVAR(c));\
5560  memmove((name)->array + UNIQVAR(idx) + UNIQVAR(c), (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
5561  memcpy((name)->array + UNIQVAR(idx), UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
5562  (name)->count += UNIQVAR(c);\
5563  }\
5564  } while(0)
5565 
5572 #define vectorSlice sliceSlice
5573 
5580 #define vectorCopy(name, start, end) ({\
5581  var UNIQVAR(strt) = start;\
5582  var UNIQVAR(ed) = end;\
5583  createAllocateVectorCount(typeof(*(name)),UNIQVAR(r), UNIQVAR(ed) - UNIQVAR(strt));\
5584  memcpy(UNIQVAR(r)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
5585  UNIQVAR(r)->count = UNIQVAR(ed) - UNIQVAR(strt);\
5586  UNIQVAR(r);\
5587  })
5588 
5594 #define vectorBCopy(name, dest, start, end) do{\
5595  if (sizeof((name)->array[0]) == sizeof((dest)->array[0])) {\
5596  var UNIQVAR(strt) = start;\
5597  var UNIQVAR(ed) = end;\
5598  if ((UNIQVAR(ed) - UNIQVAR(strt)) > (dest)->maxCount)\
5599  vectorResize(dest, UNIQVAR(ed) - UNIQVAR(strt));\
5600  memcpy((dest)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
5601  (dest)->count = UNIQVAR(ed) - UNIQVAR(strt);\
5602  }\
5603  } while(0)
5604 
5614 #define vectorSort sliceSort
5615 
5621 #define vectorEq sliceEq
5622 
5628 #define vectorHas sliceHas
5629 
5637 #define vectorIndexOf sliceIndexOf
5638 
5653 #define vectorBinarySearch sliceBinarySearch
5654 
5662 #define vectorUniq sliceUniq
5663 
5664 /*
5665  * end vector
5666  */
5667 
5668 
5716 // user parameters
5720 #define dVectorBits 6
5721 // user parameters end
5722 
5723 #define dVectorSz (1<<dVectorBits)
5724 #define dVectorMask (dVectorSz-1)
5725 
5734 #define dVectorT(typeName, elementType)\
5735  typedef struct {\
5736  int64_t count;\
5737  int64_t maxCount;\
5738  void** buffers;\
5739  elementType element;\
5740  } typeName
5741 
5742 
5743 #define createDVector(typeName, name) ;typeName name; dVectorInit(&name)
5744 
5745 #define createDVectorCount(typeName, name, count) ;typeName name; dVectorInitCount(&name, count)
5746 
5753 #define dVectorInit(a) do{\
5754  (a)->count = 0;\
5755  (a)->buffers = malloc(sizeof(void*));\
5756  (a)->buffers[0] = malloc(dVectorSz * sizeof((a)->element));\
5757  (a)->maxCount = 1;\
5758  }while(0)
5759 
5760 
5769 #define dVectorInitCount(a, count) do{\
5770  dVectorInit(a);\
5771  if (count > dVectorSz) {\
5772  (a)->buffers = realloc((a)->buffers, ((count>>dVectorBits)+1) * sizeof(void*));\
5773  rangeFrom(UNIQVAR(i), 1, (count>>dVectorBits)+1) {\
5774  (a)->buffers[UNIQVAR(i)] = malloc(dVectorSz * sizeof((a)->element));\
5775  }\
5776  (a)->maxCount = (count>>dVectorBits)+1;\
5777  }\
5778  }while(0)
5779 
5780 #define dVectorResize(a, count) do{\
5781  if (count > (a)->maxCount * dVectorSz) {\
5782  /* grow array */\
5783  (a)->buffers = realloc((a)->buffers, ((count>>dVectorBits)+1) * sizeof(void*));\
5784  rangeFrom(UNIQVAR(i), (a)->maxCount, (count>>dVectorBits)+1) {\
5785  (a)->buffers[UNIQVAR(i)] = malloc(dVectorSz * sizeof((a)->element));\
5786  }\
5787  (a)->maxCount = (count>>dVectorBits)+1;\
5788  }\
5789  /*else TODO dVector shrink */\
5790  }while(0)
5791 
5798 #define dVectorFree(a) do{\
5799  range(UNIQVAR(i), (size_t)(a)->maxCount) {\
5800  free((a)->buffers[UNIQVAR(i)]);\
5801  }\
5802  free((a)->buffers);\
5803  }while(0)
5804 
5808 #define dVectorElemType(name) typeof((name)->element)
5809 
5813 #define dVectorElemPtrType(name) typeof(&(name)->element)
5814 
5819 #define dVectorEmpty(name) (name)->count = 0
5820 
5824 #define dVectorIsEmpty(name) ((name)->count == 0)
5825 
5829 #define dVectorCount(name) (name)->count
5830 
5834 #define dVectorMaxCount(name) ((name)->maxCount * dVectorSz)
5835 
5843 #define dVectorAlloc(a) do{\
5844  if ((a)->count == dVectorMaxCount(a)) {\
5845  (a)->maxCount++;\
5846  (a)->buffers = realloc((a)->buffers, (a)->maxCount * sizeof(void*));\
5847  (a)->buffers[(a)->maxCount-1] = malloc(dVectorSz * sizeof((a)->element));\
5848  }\
5849  }while(0)
5850 
5860 #define dVectorPush(a) do{\
5861  dVectorAlloc(a);\
5862  (a)->count++;\
5863  }while(0)
5864 
5873 #define dVectorAppend(a, v) do{\
5874  dVectorAlloc(a);\
5875  if ((a)->count < dVectorMaxCount(a)) {\
5876  typeof((a)->element) *UNIQVAR(buffer) = (a)->buffers[((a)->count)>>dVectorBits];\
5877  *(UNIQVAR(buffer)+ (((a)->count)&dVectorMask)) = v;\
5878  (a)->count++;\
5879  }\
5880  }while(0)
5881 
5893 #define dVectorPop(a) ((a)->count--, *((typeof((a)->element)*)((a)->buffers[((a)->count)>>dVectorBits])+(((a)->count)&dVectorMask)))
5894 
5900 #define dVectorDelLast(a) ((a)->count--)
5901 
5902 // TODO poor perfomance #define dVectorPrepend(a, v)
5903 
5904 // TODO poor perfomance #define dVectorDequeue(a)
5905 
5906 // TODO poor perfomance #define dVectorDelFirst(a)
5907 
5916 #define dVectorAt(a, index) (*((typeof((a)->element)*)((a)->buffers[(index)>>dVectorBits])+((index)&dVectorMask)))
5917 
5926 #define dVectorPtr(a, index) ((typeof((a)->element)*)((a)->buffers[(index)>>dVectorBits])+((index)&dVectorMask))
5927 
5934 #define dVectorLast(a) (*((typeof((a)->element)*)((a)->buffers[((a)->count-1)>>dVectorBits])+(((a)->count-1)&dVectorMask)))
5935 
5942 #define dVectorLastPtr(a) ((typeof((a)->element)*)((a)->buffers[((a)->count-1)>>dVectorBits])+(((a)->count-1)&dVectorMask))
5943 
5947 #define dVectorLastIndex(a) ((a)->count-1)
5948 
5955 #define dVectorFirst(a) (*((typeof((a)->element)*)((a)->buffers[0])))
5956 
5964 #define dVectorWriteFilename(a, filename) do {\
5965  FILE *UNIQVAR(f) = fopen(filename, "w");\
5966  if (UNIQVAR(f)) {\
5967  range(UNIQVAR(i), (size_t)dVectorCount(a)) {\
5968  typeof((a)->element) *firstElement = (a)->buffers[UNIQVAR(i)/dVectorSz];\
5969  fwrite(firstElement+(UNIQVAR(i)%dVectorSz), 1, sizeof((a)->element), UNIQVAR(f));\
5970  }\
5971  fclose(UNIQVAR(f));\
5972  }\
5973  } while(0)
5974 
5982 #define dVectorWrite(a, file) do {\
5983  range(UNIQVAR(i), (size_t)dVectorCount(a)) {\
5984  typeof((a)->element) *firstElement = (a)->buffers[UNIQVAR(i)/dVectorSz];\
5985  fwrite(firstElement+(UNIQVAR(i)%dVectorSz), 1, sizeof((a)->element), file);\
5986  }\
5987  } while(0)
5988 
5996 #define dVectorReadFilename(a, filename) do {\
5997  if (fileExists(filename)) {\
5998  size_t UNIQVAR(sz) = fileSize(filename);\
5999  FILE *UNIQVAR(f) = fopen(filename, "r");\
6000  if (UNIQVAR(f)) {\
6001  range(UNIQVAR(i), UNIQVAR(sz)/sizeof((a)->element)) {\
6002  dVectorPush(a);\
6003  fread(dVectorLastPtr(a), 1, sizeof((a)->element), UNIQVAR(f));\
6004  }\
6005  fclose(UNIQVAR(f));\
6006  }\
6007  }\
6008  } while(0)
6009 
6017 #define dVectorRead(a, file) do {\
6018  fseek(file, 0 , SEEK_END);\
6019  size_t UNIQVAR(sz) = ftell(file);\
6020  fseek(file, 0 , SEEK_SET);\
6021  range(UNIQVAR(i), UNIQVAR(sz)/sizeof((a)->element)) {\
6022  dVectorPush(a);\
6023  fread(dVectorLastPtr(a), 1, sizeof((a)->element), file);\
6024  }\
6025  } while(0)
6026 
6035 #define dVectorForEach(name, element) \
6036  ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
6037  for (dVectorElemPtrType(name) element = dVectorPtr(name, 0) ; UNIQVAR(libsheepyInternalIndex) < (name)->count ; UNIQVAR(libsheepyInternalIndex)++, element = dVectorPtr(name, UNIQVAR(libsheepyInternalIndex)))
6038 
6050 #define dVectorEnumerate(name, index, element) \
6051  ; size_t index = 0 ; \
6052  for (dVectorElemPtrType(name) element = dVectorPtr(name, 0) ; index < (name)->count ; index++, element = dVectorPtr(name, index))
6053 
6054 
6055 
6056 /*
6057  * end dynamic segmented vector
6058  */
6059 
6060 
6100 //
6101 // TODO add print elements func
6102 // TODO check boundaries
6103 
6107 typedef struct {
6108  i64 last; // last element
6111  bool isEmpty;
6112 } staticArrayBase;
6113 
6124 #define staticArrayT(typeName, element, MAXCOUNT)\
6125  typedef struct {\
6126  i64 last;\
6127  i64 head;\
6128  i64 maxCount;\
6129  bool isEmpty;\
6130  element list[MAXCOUNT];\
6131  } typeName;
6132 
6133 #define createStaticArray(typeName, name) ;typeName name; staticArrayInit(name)
6134 
6142 #define staticArrayInit(name)\
6143  do{\
6144  (name).last = (name).head = 0;\
6145  (name).maxCount = COUNT_ELEMENTS((name).list);\
6146  (name).isEmpty = true;\
6147  } while(0);
6148 
6152 #define staticArrayElemType(name) typeof((name).list[0])
6153 
6157 #define staticArrayElemPtrType(name) typeof(&(name).list[0])
6158 
6163 #define staticArrayEmpty(name)\
6164  do{\
6165  (name).last = (name).head = 0;\
6166  (name).isEmpty = true;\
6167  } while(0);
6168 
6172 #define staticArrayIsEmpty(name) ((name).isEmpty)
6173 
6177 #define staticArrayIsFull(name) ((name).isEmpty ? 0 : ((((name).last+1) % (name).maxCount) == (name).head))
6178 
6182 #define staticArrayCount(name) ((name).isEmpty ? 0 : ((((name).last) >= ((name).head)) ? ((name).last-(name).head+1) : (((name).maxCount-(name).head + (name).last+1))) )
6183 
6188 #define staticArrayPush(name)\
6189  do{\
6190  if ((name).isEmpty) {\
6191  (name).isEmpty = false;\
6192  }\
6193  else {\
6194  (name).last++;\
6195  (name).last %= (name).maxCount;\
6196  }\
6197  } while(0);
6198 
6202 #define staticArrayPop(name)\
6203  do{\
6204  if (!(name).isEmpty && ((name).last == (name).head)) {\
6205  (name).isEmpty = true;\
6206  }\
6207  else if (!(name).isEmpty && ((name).last != (name).head)) {\
6208  if ((name).last)\
6209  (name).last--;\
6210  else\
6211  (name).last+=(name).maxCount-1;\
6212  }\
6213  } while(0);
6214 
6215 #define staticArrayDelLast staticArrayPop
6216 
6221 #define staticArrayPrepend(name)\
6222  do{\
6223  if ((name).isEmpty) {\
6224  (name).isEmpty = false;\
6225  }\
6226  else {\
6227  if ((name).head)\
6228  (name).head--;\
6229  else\
6230  (name).head+=(name).maxCount-1;\
6231  }\
6232  } while(0);
6233 
6237 #define staticArrayDequeue(name)\
6238  do{\
6239  if (!(name).isEmpty && ((name).last == (name).head)) {\
6240  (name).isEmpty = true;\
6241  }\
6242  else if (!(name).isEmpty && ((name).last != (name).head)) {\
6243  (name).head++;\
6244  (name).head %= (name).maxCount;\
6245  }\
6246  } while(0);
6247 
6248 #define staticArrayDelFirst staticArrayDequeue
6249 
6253 #define staticArrayGet(name, index) (name).list[(((index) >= 0) ? (index) : staticArrayCount(name) + (index) )]
6254 #define staticArrayAt staticArrayGet
6255 
6259 #define staticArrayGetIndex(name, index) ((((index) >= 0) ? (index) : staticArrayCount(name) + (index) ))
6260 
6264 #define staticArrayRef(name, index) (name).list[((((index) >= 0) ? (index) : staticArrayCount(name) + (index) ) + name.head) % name.maxCount]
6265 
6269 #define staticArrayRefIndex(name, index) (((((index) >= 0) ? (index) : staticArrayCount(name) + (index) ) + name.head) % name.maxCount)
6270 
6274 #define staticArrayLast(name) (name).list[(name).last]
6275 
6279 #define staticArrayLastIndex(name) (name).last
6280 
6284 #define staticArrayFirst(name) (name).list[(name).head]
6285 
6289 #define staticArrayFirstIndex(name) (name).head
6290 
6294 #define staticArrayDelElem(name, index) do {\
6295  if ((name).head < (name).last) {\
6296  /* move elements after index in latest static array */\
6297  if (index < (name).last) {\
6298  memmove(&(name).list[index], &(name).list[index+1], ((name).last - index) * sizeof((name).list[0]));\
6299  }\
6300  }\
6301  elif ((name).head > (name).last) {\
6302  if (index >= (name).head) {\
6303  /* move elements after index in latest static array */\
6304  if (index < (name).maxCount - 1) {\
6305  memmove(&(name).list[index], &(name).list[index+1], ((name).maxCount - index -1) * sizeof((name).list[0]));\
6306  }\
6307  /* move list[0] to list[maxCount-1] */\
6308  /* then shift elements in [1..last+1] to [0..last] if needed */\
6309  staticArrayAt((name), (name).maxCount-1) = staticArrayAt((name), 0);\
6310  if ((name).last > 0) {\
6311  memmove(&(name).list[0], &(name).list[1], (name).last * sizeof((name).list[0]));\
6312  }\
6313  }\
6314  else {\
6315  /* 0 < index < last+1 */\
6316  /* move elements after index in latest static array */\
6317  if (index < (name).last) {\
6318  memmove(&(name).list[index], &(name).list[index+1], ((name).last - index) * sizeof((name).list[0]));\
6319  }\
6320  }\
6321  }\
6322  staticArrayDelLast((name));\
6323  } while(0)
6324 
6332 #define staticArrayWriteFilename(name, filename) do {\
6333  FILE *UNIQVAR(f) = fopen(filename, "w");\
6334  if (UNIQVAR(f)) {\
6335  if ((name).head <= (name).last) {\
6336  fwrite(&((name).list[(name).head]), 1, (size_t)staticArrayCount(name) * sizeof((name).list[0]), UNIQVAR(f));\
6337  } else {\
6338  /* write from head to maxcount and then from 0 to last*/\
6339  fwrite(&((name).list[(name).head]), 1, (size_t)((name).maxCount - (name).head) * sizeof((name).list[0]), UNIQVAR(f));\
6340  fwrite(&((name).list[(name).head])+((name).maxCount - (name).head), 1, (size_t)((name).last+1) * sizeof((name).list[0]), UNIQVAR(f));\
6341  }\
6342  fclose(UNIQVAR(f));\
6343  }\
6344  } while(0)
6345 
6353 #define staticArrayWrite(name, file) do {\
6354  if ((name).head <= (name).last) {\
6355  fwrite(&((name).list[(name).head]), 1, (size_t)staticArrayCount(name) * sizeof((name).list[0]), file);\
6356  } else {\
6357  /* write from head to maxcount and then from 0 to last*/\
6358  fwrite(&((name).list[(name).head]), 1, (size_t)((name).maxCount - (name).head) * sizeof((name).list[0]), file);\
6359  fwrite(&((name).list[(name).head])+((name).maxCount - (name).head), 1, (size_t)((name).last+1) * sizeof((name).list[0]), file);\
6360  }\
6361  } while(0)
6362 
6370 #define staticArrayReadFilename(name, filename) do {\
6371  if (fileExists(filename)) {\
6372  size_t UNIQVAR(sz) = fileSize(filename);\
6373  if (UNIQVAR(sz) > sizeof((name).list)) break;\
6374  /* check that UNIQVAR(sz) is a multiple of sizeof((name).list[0]), if not the file data doesnt fit the array */\
6375  if (UNIQVAR(sz) % sizeof((name).list[0])) break;\
6376  FILE *UNIQVAR(f) = fopen(filename, "r");\
6377  if (UNIQVAR(f)) {\
6378  fread((name).list, 1, UNIQVAR(sz), UNIQVAR(f));\
6379  fclose(UNIQVAR(f));\
6380  (name).head = 0;\
6381  if (UNIQVAR(sz)) {\
6382  (name).last = (UNIQVAR(sz) / sizeof((name).list[0])) - 1;\
6383  (name).isEmpty = false;\
6384  }\
6385  else {\
6386  (name).last = 0;\
6387  (name).isEmpty = true;\
6388  }\
6389  }\
6390  }\
6391  } while(0)
6392 
6400 #define staticArrayRead(name, file) do {\
6401  fseek(file, 0 , SEEK_END);\
6402  size_t UNIQVAR(sz) = ftell(file);\
6403  fseek(file, 0 , SEEK_SET);\
6404  if (UNIQVAR(sz) > sizeof((name).list)) break;\
6405  /* check that UNIQVAR(sz) is a multiple of sizeof((name).list[0]), if not the file data doesnt fit the array */\
6406  if (UNIQVAR(sz) % sizeof((name).list[0])) break;\
6407  fread((name).list, 1, UNIQVAR(sz), file);\
6408  (name).head = 0;\
6409  if (UNIQVAR(sz)) {\
6410  (name).last = (UNIQVAR(sz) / sizeof((name).list[0])) - 1;\
6411  (name).isEmpty = false;\
6412  }\
6413  else {\
6414  (name).last = 0;\
6415  (name).isEmpty = true;\
6416  }\
6417  } while(0)
6418 
6427 #define staticArrayForEach(name, element) \
6428  ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
6429  for (staticArrayElemPtrType(name) element = &staticArrayRef(name, 0) ; UNIQVAR(libsheepyInternalIndex) < staticArrayCount(name) ; UNIQVAR(libsheepyInternalIndex)++, element = &staticArrayRef(name, UNIQVAR(libsheepyInternalIndex)))
6430 
6442 #define staticArrayEnumerate(name, index, element) \
6443  ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
6444  ; size_t index = name.head ; \
6445  for (staticArrayElemPtrType(name) element = &staticArrayRef(name, 0) ; UNIQVAR(libsheepyInternalIndex) < staticArrayCount(name) ; UNIQVAR(libsheepyInternalIndex)++, index = (name.head + UNIQVAR(libsheepyInternalIndex)) % name.maxCount, element = &staticArrayRef(name, index))
6446 
6499 #define indexer staticArrayBase
6500 
6507 #define indexerT(typeName, INT_TYPE)\
6508  typedef struct {\
6509  INT_TYPE last;\
6510  INT_TYPE head;\
6511  INT_TYPE maxCount;\
6512  bool isEmpty;\
6513  } typeName;
6514 
6515 #define createIndexer(typeName, name, maxCount) ;typeName name; indexerInit(name, maxCount)
6516 
6526 #define indexerInit(name, MAXCOUNT)\
6527  do{\
6528  (name).last = (name).head = 0;\
6529  (name).maxCount = MAXCOUNT;\
6530  (name).isEmpty = true;\
6531  } while(0);
6532 
6533 #define indexerPInit ringInit
6534 
6539 #define indexerEmpty staticArrayEmpty
6540 #define indexerPEmpty ringEmpty
6541 
6545 #define indexerIsEmpty staticArrayIsEmpty
6546 #define indexerPIsEmpty ringIsEmpty
6547 
6551 #define indexerIsFull staticArrayIsFull
6552 #define indexerPIsFull ringIsFull
6553 
6557 #define indexerCount staticArrayCount
6558 #define indexerPCount ringCount
6559 
6564 #define indexerPush staticArrayPush
6565 #define indexerPPush ringPush
6566 
6570 #define indexerPop staticArrayPop
6571 #define indexerPPop ringPop
6572 
6577 #define indexerPrepend staticArrayPrepend
6578 #define indexerPPrepend ringPrepend
6579 
6583 #define indexerDequeue staticArrayDequeue
6584 #define indexerPDequeue ringDequeue
6585 
6589 #define indexerRef(name, index) (((((index) >= 0) ? (index) : indexerCount(name) + (index) ) + name.head) % name.maxCount)
6590 #define indexerPRef(name, index) (((((index) >= 0) ? (index) : indexerPCount(name) + (index) ) + name->head) % name->maxCount)
6591 
6595 #define indexerLast(name) name.last
6596 #define indexerPLast(name) (name)->last
6597 
6601 #define indexerFirst(name) (name.head)
6602 #define indexerPFirst(name) (name)->head
6603 
6604 
6639 #define ringBase staticArrayBase
6640 
6652 #define ringMake staticArrayT
6653 
6663 #define ringStaticInit staticArrayInit
6664 
6665 // initialize ring/pointer to staticArray
6666 int ringInit(void *ring, int maxCount);
6667 
6668 // empty ring
6669 int ringEmpty(void *ring);
6670 
6671 // is ring Empty
6672 int ringIsEmpty(void *ring);
6673 
6674 // is ring Full
6675 int ringIsFull(void *ring);
6676 
6677 // return elements count
6678 ssize_t ringCount(void *ring);
6679 
6680 
6681 // push element to ring (only increases last, use ringSend), use ringLast to access the element
6682 i64 ringPush(void *ring);
6683 
6684 
6685 // pop element from ring (only decreases last)
6686 int ringPop(void *ring);
6687 
6688 
6689 // prepend element to ring (only decreases head), use ringFirst to access the element
6690 i64 ringPrepend(void *ring);
6691 
6692 // dequeue element from ring (only increases head, use ringRecv)
6693 int ringDequeue(void *ring);
6694 
6698 #define ringGet(name, index) (name)->list[(((index) >= 0) ? (index) : ringCount(name) + (index) )]
6699 
6703 #define ringRef(name, index) (name)->list[((((index) >= 0) ? (index) : ringCount(name) + (index) ) + name->head) % name->maxCount]
6704 
6708 #define ringLast(name) (name)->list[(name)->last]
6709 
6713 #define ringLastIndex(name) (name)->last
6714 
6718 #define ringFirst(name) (name)->list[(name)->head]
6719 
6720 
6729 #define ringSend(name, value)\
6730  do {\
6731  if (ringPush(name) >= 0) ringLast(name) = value;\
6732  } while(0);
6733 
6734 // send data and get ring status
6735 #define ringSendSt(status, name, value)\
6736  do {\
6737  if ((status = ringPush(name)) >= 0) ringLast(name) = value;\
6738  } while(0);
6739 
6740 
6749 #define ringRecv(name, result)\
6750  do {\
6751  result = ringFirst(name);\
6752  ringDequeue(name);\
6753  } while(0);
6754 
6755 // receive data and get ring status
6756 #define ringRecvSt(status, name, result)\
6757  do {\
6758  if ((status = ringIsEmpty(name)) == 0) {\
6759  result = ringFirst(name);\
6760  ringDequeue(name);\
6761  }\
6762  } while(0);
6763 
6815 // schedule fibers
6816 void scheduler(void);
6817 
6818 // the scheduler takes slot 0
6819 // the system can handle tCount-1 fibers
6820 #define tCount 10
6821 
6828 typedef struct {int slot;} fiberBaseT;
6829 
6833 staticArrayT(fiberLT, int, tCount);
6834 
6838 typedef struct {
6842  jmp_buf jumpBuffers[tCount];
6846  fiberLT L;
6850  fiberLT startL;
6854  void *context[tCount];
6858  void (*F[tCount])(int thisSlot);
6859 } fibersT;
6860 
6864 extern fibersT fibers;
6865 
6869 #define fiberCtx(thisSlot) fibers.context[thisSlot]
6870 
6874 typedef void (*fiberFT)(int);
6875 
6879 bool fiberAdd(void *ctx, int thisSlot, fiberFT func);
6880 
6884 bool fiberPrepend(void *ctx, int thisSlot, fiberFT func);
6885 
6896 #define startJump(func)\
6897  if (!setjmp(fibers.jumpBuffers[0])) {\
6898  func;\
6899  }
6900 
6901 #if !__sun__
6902 
6908 #define yield(slotValue, slot)\
6909  if (!(slotValue = setjmp(fibers.jumpBuffers[slot]))) {\
6910  staticArrayPush(fibers.L);\
6911  staticArrayLast(fibers.L) = slot;\
6912  longjmp(fibers.jumpBuffers[0], 1);\
6913  }
6914 #endif
6915 
6919 #define fiberEnd(slot)\
6920  if (!setjmp(fibers.jumpBuffers[slot])) {\
6921  longjmp(fibers.jumpBuffers[0], 1);\
6922  }
6923 
6924 // internal for scheduler
6925 #define schedulerYield(backToSlot)\
6926  if (!setjmp(fibers.jumpBuffers[0])) {\
6927  longjmp(fibers.jumpBuffers[backToSlot], backToSlot);\
6928  }
6929 
6930 
6931 
6980 // user parameters
6984 #define dArrayBits 6
6985 // user parameters end
6986 
6987 #define dArraySz (1<<dArrayBits)
6988 #define dArrayMask (dArraySz-1)
6989 
6998 #define dArrayT(typeName, elementType)\
6999  typedef struct {\
7000  int64_t last;\
7001  int64_t head;\
7002  int64_t maxCount;\
7003  void** buffers;\
7004  elementType element;\
7005  } typeName
7006 
7007 
7008 #define createDArray(typeName, name) ;typeName name; dArrayInit(&name)
7009 
7010 #define createDArrayCount(typeName, name, count) ;typeName name; dArrayInitCount(&name, count)
7011 
7018 #define dArrayInit(a) do{\
7019  (a)->last = (a)->head = 0;\
7020  (a)->buffers = malloc(sizeof(void*));\
7021  (a)->buffers[0] = malloc(dArraySz * sizeof((a)->element));\
7022  (a)->maxCount = 1;\
7023  }while(0)
7024 
7033 #define dArrayInitCount(a, count) do{\
7034  dArrayInit(a);\
7035  if ((count) > dArraySz) {\
7036  (a)->buffers = realloc((a)->buffers, (((count)>>dArrayBits)+1) * sizeof(void*));\
7037  rangeFrom(UNIQVAR(i), 1, ((count)>>dArrayBits)+1) {\
7038  (a)->buffers[UNIQVAR(i)] = malloc(dArraySz * sizeof((a)->element));\
7039  }\
7040  (a)->maxCount = ((count)>>dArrayBits)+1;\
7041  }\
7042  }while(0)
7043 
7044 #define dArrayResize(a, count) do{\
7045  if ((count) > (a)->maxCount * dArraySz) {\
7046  /* grow array */\
7047  (a)->buffers = realloc((a)->buffers, (((count)>>dArrayBits)+1) * sizeof(void*));\
7048  rangeFrom(UNIQVAR(i), (a)->maxCount, ((count)>>dArrayBits)+1) {\
7049  (a)->buffers[UNIQVAR(i)] = malloc(dArraySz * sizeof((a)->element));\
7050  }\
7051  (a)->maxCount = ((count)>>dArrayBits)+1;\
7052  }\
7053  /*else TODO dArray shrink */\
7054  }while(0)
7055 
7062 #define dArrayFree dVectorFree
7063 
7067 #define dArrayElemType(a) typeof((a)->element)
7068 
7072 #define dArrayElemPtrType(a) typeof(&(a)->element)
7073 
7078 #define dArrayEmpty(name) do{\
7079  (name)->last = (name)->head = 0;\
7080  } while(0);
7081 
7085 #define dArrayIsEmpty(name) ((name)->head == (name)->last)
7086 
7090 #define dArrayCount(name) ((name)->last - (name)->head)
7091 
7095 #define dArrayMaxCount(name) ((name)->maxCount * dArraySz)
7096 
7104 #define dArrayAlloc(a) do{\
7105  if ((a)->last == dArrayMaxCount(a)) {\
7106  (a)->maxCount++;\
7107  (a)->buffers = realloc((a)->buffers, (size_t)(a)->maxCount * sizeof(void*));\
7108  (a)->buffers[(a)->maxCount-1] = malloc(dArraySz * sizeof((a)->element));\
7109  }\
7110  }while(0)
7111 
7121 #define dArrayPush(a) do{\
7122  dArrayAlloc(a);\
7123  (a)->last++;\
7124  }while(0)
7125 
7134 #define dArrayAppend(a, v) do{\
7135  dArrayAlloc(a);\
7136  if ((a)->last < dArrayMaxCount(a)) {\
7137  typeof((a)->element) *UNIQVAR(buffer) = (a)->buffers[((a)->last)>>dArrayBits];\
7138  *(UNIQVAR(buffer)+ (((a)->last)&dArrayMask)) = v;\
7139  (a)->last++;\
7140  }\
7141  }while(0)
7142 
7154 #define dArrayPop(a) ((a)->last--, *((typeof((a)->element)*)((a)->buffers[((a)->last)>>dArrayBits])+(((a)->last)&dArrayMask)))
7155 
7161 #define dArrayDelLast(a) ((a)->last--)
7162 
7171 #define dArrayPrepend(a, v) do{\
7172  if ((a)->head > 0) {\
7173  (a)->head--;\
7174  typeof((a)->element) *UNIQVAR(buffer) = (a)->buffers[((a)->head)>>dArrayBits];\
7175  *(UNIQVAR(buffer)+ (((a)->head)&dArrayMask)) = v;\
7176  }\
7177  }while(0)
7178 
7190 #define dArrayDequeue(a) ((a)->head++, *((typeof((a)->element)*)((a)->buffers[((a)->head-1)>>dArrayBits])+(((a)->head-1)&dArrayMask)))
7191 
7197 #define dArrayDelFirst(a) ((a)->head++)
7198 
7207 #define dArrayAt(a, index) (*((typeof((a)->element)*)((a)->buffers[(index)>>dArrayBits])+((index)&dArrayMask)))
7208 
7217 #define dArrayPtr(a, index) ((typeof((a)->element)*)((a)->buffers[(index)>>dArrayBits])+((index)&dArrayMask))
7218 
7222 #define dArraySet(a, index, v) do{\
7223  var UNIQVAR(idx) = index;\
7224  if (UNIQVAR(idx) < (a)->last) {\
7225  /* index is inside current array */\
7226  dArrayAt(a, UNIQVAR(idx)) = v;\
7227  if (UNIQVAR(idx) < (a)->head) {\
7228  /* update head since index is lower */\
7229  (a)->head = UNIQVAR(idx);\
7230  }\
7231  }\
7232  else {\
7233  /* index is after last element */\
7234  /* check if index is under maxCount */\
7235  if (UNIQVAR(idx) >= dArrayMaxCount(a)) {\
7236  /* resize array */\
7237  dArrayResize(a, UNIQVAR(idx)+1);\
7238  }\
7239  dArrayAt(a, UNIQVAR(idx)) = v;\
7240  /* update last since index is higher*/\
7241  (a)->last = UNIQVAR(idx)+1;\
7242  }\
7243  }while(0)
7244 
7256 #define dArraySparseSet(a, index, v) do{\
7257  var UNIQVAR(idx) = index;\
7258  var UNIQVAR(bIdx) = UNIQVAR(idx)>>dArrayBits;\
7259  if (UNIQVAR(idx) >= dArrayMaxCount(a)) {\
7260  /* sparse resize array - grow array */\
7261  (a)->buffers = realloc((a)->buffers, (((UNIQVAR(bIdx)+1)>>dArrayBits)+1) * sizeof(void*));\
7262  /* empty segments are marked with NULL */\
7263  memset(&(a)->buffers[(a)->maxCount], 0, (UNIQVAR(bIdx)+1) - (a)->maxCount);\
7264  (a)->maxCount = UNIQVAR(bIdx)+1;\
7265  /* allocate new segment */\
7266  (a)->buffers[UNIQVAR(bIdx)] = malloc(dArraySz * sizeof((a)->element));\
7267  dArrayAt(a, UNIQVAR(idx)) = v;\
7268  }\
7269  else {\
7270  /* check if the segment is already allocated */\
7271  if (!(a)->buffers[UNIQVAR(bIdx)]) {\
7272  /* allocate new segment */\
7273  (a)->buffers[UNIQVAR(bIdx)] = malloc(dArraySz * sizeof((a)->element));\
7274  }\
7275  dArrayAt(a, UNIQVAR(idx)) = v;\
7276  }\
7277  }while(0)
7278 
7285 #define dArrayLast(a) (*((typeof((a)->element)*)((a)->buffers[((a)->last-1)>>dArrayBits])+(((a)->last-1)&dArrayMask)))
7286 
7293 #define dArrayLastPtr(a) ((typeof((a)->element)*)((a)->buffers[((a)->last-1)>>dArrayBits])+(((a)->last-1)&dArrayMask))
7294 
7298 #define dArrayLastIndex(a) ((a)->last-1)
7299 
7303 #define dArrayLastIndexVar(a) ((a)->last)
7304 
7311 #define dArrayFirst(a) (*((typeof((a)->element)*)((a)->buffers[((a)->head)>>dArrayBits])+((a)->head)&dArrayMask))
7312 
7316 #define dArrayFirstIndex(a) ((a)->head)
7317 
7325 #define dArrayWriteFilename(a, filename) do {\
7326  FILE *UNIQVAR(f) = fopen(filename, "w");\
7327  if (UNIQVAR(f)) {\
7328  range(UNIQVAR(i), (size_t)dArrayCount(a)) {\
7329  typeof((a)->element) *firstElement = (a)->buffers[UNIQVAR(i)/dArraySz];\
7330  fwrite(firstElement+(UNIQVAR(i)%dArraySz), 1, sizeof((a)->element), UNIQVAR(f));\
7331  }\
7332  fclose(UNIQVAR(f));\
7333  }\
7334  } while(0)
7335 
7343 #define dArrayWrite(a, file) do {\
7344  range(UNIQVAR(i), (size_t)dArrayCount(a)) {\
7345  typeof((a)->element) *firstElement = (a)->buffers[UNIQVAR(i)/dArraySz];\
7346  fwrite(firstElement+(UNIQVAR(i)%dArraySz), 1, sizeof((a)->element), file);\
7347  }\
7348  } while(0)
7349 
7357 #define dArrayReadFilename(a, filename) do {\
7358  if (fileExists(filename)) {\
7359  size_t UNIQVAR(sz) = fileSize(filename);\
7360  FILE *UNIQVAR(f) = fopen(filename, "r");\
7361  if (UNIQVAR(f)) {\
7362  range(UNIQVAR(i), UNIQVAR(sz)/sizeof((a)->element)) {\
7363  dArrayPush(a);\
7364  fread(dArrayLastPtr(a), 1, sizeof((a)->element), UNIQVAR(f));\
7365  }\
7366  fclose(UNIQVAR(f));\
7367  }\
7368  }\
7369  } while(0)
7370 
7378 #define dArrayRead(a, file) do {\
7379  fseek(file, 0 , SEEK_END);\
7380  size_t UNIQVAR(sz) = ftell(file);\
7381  fseek(file, 0 , SEEK_SET);\
7382  range(UNIQVAR(i), UNIQVAR(sz)/sizeof((a)->element)) {\
7383  dArrayPush(a);\
7384  fread(dArrayLastPtr(a), 1, sizeof((a)->element), file);\
7385  }\
7386  } while(0)
7387 
7396 #define dArrayForEach(name, element) \
7397  ;size_t UNIQVAR(libsheepyInternalIndex) = (name)->head; \
7398  for (dArrayElemPtrType(name) element = dArrayPtr(name, (name)->head) ; UNIQVAR(libsheepyInternalIndex) < (name)->last + 1 ; UNIQVAR(libsheepyInternalIndex)++, element = dArrayPtr(name, UNIQVAR(libsheepyInternalIndex)))
7399 
7411 #define dArrayEnumerate(name, index, element) \
7412  ; size_t index = (name)->head; \
7413  for (dArrayElemPtrType(name) element = dArrayPtr(name, (name)->head) ; index < (name)->last + 1 ; index++, element = dArrayPtr(name, index))
7414 
7415 
7416 
7417 /*
7418  * end dynamic array
7419  */
7420 
7421 
7469 #define slabSz 64
7470 
7479 #define slabT(typeName, elementType)\
7480  typedef struct {\
7481  int64_t last;\
7482  int64_t head;\
7483  int64_t maxCount;\
7484  elementType *array;\
7485  } typeName
7486 
7487 
7488 #define createSlab(typeName, name) ;typeName name; slabInit(&name)
7489 
7490 #define createSlabCount(typeName, name, count) ;typeName name; slabInitCount(&name, count)
7491 
7498 #define slabInit(a) do{\
7499  (a)->last = (a)->head = 0;\
7500  (a)->array = malloc(sizeof(*((a)->array)) * slabSz);\
7501  (a)->maxCount = slabSz;\
7502  }while(0)
7503 
7504 
7513 #define slabInitCount(a, count) do{\
7514  var UNIQVAR(c) = count;\
7515  (a)->last = (a)->head = 0;\
7516  (a)->array = malloc(sizeof(*((a)->array)) * UNIQVAR(c));\
7517  (a)->maxCount = UNIQVAR(c);\
7518  }while(0)
7519 
7520 #define slabResize(a, count) do{\
7521  var UNIQVAR(c) = count;\
7522  (a)->array = realloc((a)->array, sizeof(*((a)->array)) * UNIQVAR(c));\
7523  (a)->maxCount = UNIQVAR(c);\
7524  if (((a)->last >= (a)->maxCount) || ((a)->head >= (a)->maxCount)) {\
7525  /* shrinking error - head or last outside the new array, reset to 0 */\
7526  (a)->last = (a)->head = 0;\
7527  }\
7528  }while(0)
7529 
7536 #define slabFree sliceFree
7537 
7541 #define slabElemType(name) typeof((name)->array[0])
7542 
7546 #define slabElemPtrType(name) typeof(&(name)->array[0])
7547 
7551 #define slabEmpty(name) do{\
7552  (name)->last = (name)->head = 0;\
7553  } while(0);
7554 
7558 #define slabIsEmpty(name) ((name)->head == (name)->last)
7559 
7563 #define slabCount(name) ((name)->last - (name)->head)
7564 
7568 #define slabMaxCount vectorMaxCount
7569 
7577 #define slabAlloc(a) do{\
7578  if ((a)->last == slabMaxCount(a)) {\
7579  (a)->maxCount += slabSz;\
7580  slabResize(a, (a)->maxCount);\
7581  }\
7582  }while(0)
7583 
7591 #define slabPush(a) do{\
7592  slabAlloc(a);\
7593  (a)->last++;\
7594  }while(0)
7595 
7604 #define slabAppend(a, v) do{\
7605  slabAlloc(a);\
7606  if ((a)->last < slabMaxCount(a)) {\
7607  *( (a)->array + (a)->last ) = v;\
7608  (a)->last++;\
7609  }\
7610  }while(0)
7611 
7623 #define slabPop(a) ((a)->last--, *((a)->array + (a)->last))
7624 
7630 #define slabDelLast(a) ((a)->last--)
7631 
7640 #define slabPrepend(a, v) do{\
7641  if ((a)->head > 0) {\
7642  (a)->head--;\
7643  *( (a)->array + (a)->head ) = v;\
7644  }\
7645  }while(0)
7646 
7658 #define slabDequeue(a) ((a)->head++, *((a)->array + (a)->head -1))
7659 
7665 #define slabDelFirst(a) ((a)->head++)
7666 
7675 #define slabAt sliceAt
7676 
7685 #define slabPtr slicePtr
7686 
7693 #define slabLast(a) (*((a)->array + (a)->last -1))
7694 
7701 #define slabLastPtr(a) ((a)->array + (a)->last -1)
7702 
7706 #define slabLastIndex(a) ((a)->last-1)
7707 
7711 #define slabLastIndexVar(a) ((a)->last)
7712 
7719 #define slabFirst(a) (*((a)->array + (a)->head))
7720 
7724 #define slabFirstIndex(a) ((a)->head)
7725 
7733 #define slabWriteFilename(a, filename) do {\
7734  FILE *UNIQVAR(f) = fopen(filename, "w");\
7735  if (UNIQVAR(f)) {\
7736  fwrite((a)->array + (a)->head, 1, sizeof(*((a)->array)) * slabCount(a), UNIQVAR(f));\
7737  fclose(UNIQVAR(f));\
7738  }\
7739  } while(0)
7740 
7748 #define slabWrite(a, file) fwrite((a)->array + (a)->head, 1, sizeof(*((a)->array)) * slabCount(a), file)
7749 
7757 #define slabReadFilename(a, filename) do {\
7758  if (fileExists(filename)) {\
7759  size_t UNIQVAR(sz) = fileSize(filename);\
7760  FILE *UNIQVAR(f) = fopen(filename, "r");\
7761  if (UNIQVAR(f)) {\
7762  range(UNIQVAR(i), UNIQVAR(sz)/sizeof(*((a)->array))) {\
7763  slabPush(a);\
7764  fread(slabLastPtr(a), 1, sizeof(*((a)->array)), UNIQVAR(f));\
7765  }\
7766  fclose(UNIQVAR(f));\
7767  }\
7768  }\
7769  } while(0)
7770 
7778 #define slabRead(a, file) do {\
7779  fseek(file, 0 , SEEK_END);\
7780  size_t UNIQVAR(sz) = ftell(file);\
7781  fseek(file, 0 , SEEK_SET);\
7782  range(UNIQVAR(i), UNIQVAR(sz)/sizeof(*((a)->array))) {\
7783  slabPush(a);\
7784  fread(slabLastPtr(a), 1, sizeof(*((a)->array)), file);\
7785  }\
7786  } while(0)
7787 
7796 #define slabForEach(name, element) \
7797  ;size_t UNIQVAR(libsheepyInternalIndex) = (name)->head; \
7798  for (slabElemPtrType(name) element = slabPtr(name, (name)->head) ; UNIQVAR(libsheepyInternalIndex) < (name)->last + 1 ; UNIQVAR(libsheepyInternalIndex)++, element = slabPtr(name, UNIQVAR(libsheepyInternalIndex)))
7799 
7811 #define slabEnumerate(name, index, element) \
7812  ; size_t index = (name)->head; \
7813  for (slabElemPtrType(name) element = slabPtr(name, (name)->head) ; index < (name)->last + 1 ; index++, element = slabPtr(name, index))
7814 
7815 
7816 /*
7817  * end slab
7818  */
7819 
7820 
7850 #define staticBitsetT(typeName, containerType, count)\
7851  typedef struct {containerType map[BUCKETS(count, 8 * sizeof(containerType))];} typeName;
7852 
7853 #define staticBitsetInit staticBitsetClear
7854 
7856 #define staticBitsetCount(name) (sizeof((name)->map) * 8)
7857 
7859 #define staticBitsetClear(name) memset(name, 0, sizeof(*(name)));
7860 
7862 #define staticBitsetBucket(name, index) (name)->map[index / (8 * sizeof((name)->map[0]))]
7863 
7865 #define staticBitset0(name, index) do{\
7866  var UNIQVAR(idx) = index;\
7867  size_t byteOffset = UNIQVAR(idx) / (8 * sizeof((name)->map[0]));\
7868  size_t bitOffset = UNIQVAR(idx) % (8 * sizeof((name)->map[0]));\
7869  (name)->map[byteOffset] &= 0xFFFFFFFFFFFFFFFFUL ^ (1UL<<bitOffset);\
7870  } while(0)
7871 
7873 #define staticBitset1(name, index) do{\
7874  var UNIQVAR(idx) = index;\
7875  size_t byteOffset = UNIQVAR(idx) / (8 * sizeof((name)->map[0]));\
7876  size_t bitOffset = UNIQVAR(idx) % (8 * sizeof((name)->map[0]));\
7877  (name)->map[byteOffset] |= 1UL<<bitOffset;\
7878  } while(0)
7879 
7881 #define staticBitsetSet(name, index, value) do{\
7882  var UNIQVAR(idx) = index;\
7883  size_t byteOffset = UNIQVAR(idx) / (8 * sizeof((name)->map[0]));\
7884  size_t bitOffset = UNIQVAR(idx) % (8 * sizeof((name)->map[0]));\
7885  /* performance is about the same as the if version with gcc 6.3 on skylake cpu, use the less obscure version - (name)->map[byteOffset] = ( (name)->map[byteOffset] & ~(1UL<<bitOffset)) | (-(value) & (1UL<<bitOffset));*/\
7886  if (!value)\
7887  (name)->map[byteOffset] &= 0xFFFFFFFFFFFFFFFFUL ^ (1UL<<bitOffset);\
7888  else\
7889  (name)->map[byteOffset] |= 1UL<<bitOffset;\
7890  } while(0)
7891 
7893 #define staticBitsetInv(name, index) do{\
7894  var UNIQVAR(idx) = index;\
7895  size_t byteOffset = UNIQVAR(idx) / (8 * sizeof((name)->map[0]));\
7896  size_t bitOffset = UNIQVAR(idx) % (8 * sizeof((name)->map[0]));\
7897  (name)->map[byteOffset] ^= 1UL<<bitOffset;\
7898  } while(0)
7899 
7901 #define staticBitsetGet(name, index) ({\
7902  var UNIQVAR(idx) = index;\
7903  size_t byteOffset = UNIQVAR(idx) / (8 * sizeof((name)->map[0]));\
7904  size_t bitOffset = UNIQVAR(idx) % (8 * sizeof((name)->map[0]));\
7905  ((name)->map[byteOffset] & (1UL<<bitOffset)) == 1UL<<bitOffset;\
7906  })
7907 
7921 #define bitsetModulo 8
7922 
7924 #define bitsetBucket(name, index) (name)->map[index / (bitsetModulo)]
7925 
7931 #define bitset0(name, at, index) do{\
7932  var UNIQVAR(idx) = index;\
7933  size_t byteOffset = UNIQVAR(idx) / (bitsetModulo);\
7934  size_t bitOffset = UNIQVAR(idx) % (bitsetModulo);\
7935  at(name, byteOffset) &= 0xFFFFFFFFFFFFFFFFUL ^ (1UL<<bitOffset);\
7936  } while(0)
7937 
7943 #define bitset1(name, at, index) do{\
7944  var UNIQVAR(idx) = index;\
7945  size_t byteOffset = UNIQVAR(idx) / (bitsetModulo);\
7946  size_t bitOffset = UNIQVAR(idx) % (bitsetModulo);\
7947  at(name, byteOffset) |= 1UL<<bitOffset;\
7948  } while(0)
7949 
7955 #define bitsetSet(name, at, index, value) do{\
7956  var UNIQVAR(idx) = index;\
7957  size_t byteOffset = UNIQVAR(idx) / (bitsetModulo);\
7958  size_t bitOffset = UNIQVAR(idx) % (bitsetModulo);\
7959  /* performance is about the same as the if version with gcc 6.3 on skylake cpu, use the less obscure version - at(name, byteOffset) = ( at(name, byteOffset) & ~(1UL<<bitOffset)) | (-(value) & (1UL<<bitOffset)); */\
7960  if (!value)\
7961  at(name, byteOffset) &= 0xFFFFFFFFFFFFFFFFUL ^ (1UL<<bitOffset);\
7962  else\
7963  at(name, byteOffset) |= 1UL<<bitOffset;\
7964  } while(0)
7965 
7971 #define bitsetInv(name, at, index) do{\
7972  var UNIQVAR(idx) = index;\
7973  size_t byteOffset = UNIQVAR(idx) / (bitsetModulo);\
7974  size_t bitOffset = UNIQVAR(idx) % (bitsetModulo);\
7975  at(name, byteOffset) ^= 1UL<<bitOffset;\
7976  } while(0)
7977 
7984 #define bitsetGet(name, at, index) ({\
7985  var UNIQVAR(idx) = index;\
7986  size_t byteOffset = UNIQVAR(idx) / (bitsetModulo);\
7987  size_t bitOffset = UNIQVAR(idx) % (bitsetModulo);\
7988  (at(name, byteOffset) & (1UL<<bitOffset)) == 1UL<<bitOffset;\
7989  })
7990 
8034 #define FIELD_SET(dst, val, msb, lsb) dst = (/*clear field in dst*/ (dst) & ((0xFFFFFFFFFFFFFFFEUL << (msb)) | ((1UL<<(lsb))-1) )) | (/*clear highest bits in val and shift to field lsb*/(~(0xFFFFFFFFFFFFFFFEUL << ((msb)-(lsb))) & (val)) << (lsb))
8035 
8036 #define FIELD_GET EXTRACT
8037 
8053 #define FIELD_SETL(dst, index, val, len) FIELD_SET(dst, val, ((index)+1)*(len)-1, (index)*(len))
8054 
8068 #define BITFIELD_SET(array, index, val, len) FIELD_SET((array)[((index)*(len))/64], val, ((index)*(len))%64+(len)-1, ((index)*(len))%64)
8069 
8081 #define BITFIELD_GET(array, index, len) EXTRACT((array)[((index)*(len))/64], ((index)*(len))%64+(len)-1, ((index)*(len))%64)
8082 
8086 #define BITFIELD_SIZE(count, len, containerType) BUCKETS((count)*(len), 8 * sizeof(containerType))
8087 
8091 #define BITFIELD_VAR(array, count, len) u64 array[BITFIELD_SIZE(count, len, u64)]
8092 
8097 // get monotonic time in ns
8098 uint64_t getMonotonicTime(void) MUST_CHECK;
8099 
8100 // sleep nanoseconds
8101 int nanoSleepF(uint64_t time) MUST_CHECK;
8102 #define nanoSleep(time) pError0(nanoSleepF(time))
8103 
8105 #define nanoSleep(time) pError0(nanoSleepF(time))
8106 
8108 #define nanoSleepE(time, cmd) pErrorCmd(nanoSleepF(time), == 0, cmd)
8109 
8111 #define usSleep(time) pError0(nanoSleepF(1000 * (uint64_t)time))
8112 
8114 #define msSleep(time) pError0(nanoSleepF(1000000 * (uint64_t)time))
8115 
8116 
8117 #ifdef __GNUC__
8118 #define UNUSED __attribute__ ((unused))
8119 #define DEPRECATED __attribute__ ((deprecated))
8120 #define PACKED __attribute__((__packed__))
8121 
8137 #define CLEANUP(func) __attribute__((cleanup(func)))
8138 
8150 #if __GNUC__ >= 7
8151 #define FALLTHRU __attribute__ ((fallthrough))
8152 #else
8153 #define FALLTHRU
8154 #endif
8155 
8157 #define AINLINE inline __attribute__ ((always_inline))
8158 
8160 #define NOINLINE __attribute__ ((noinline))
8161 
8168 //#define PURE __attribute__ ((pure))
8169 
8175 //#define CONST __attribute__ ((const))
8176 
8178 #define NORETURN __attribute__ ((noreturn))
8179 
8181 #define AMALLOC __attribute__ ((malloc))
8182 
8184 #define USED __attribute__ ((used))
8185 
8187 #define ALIGN(X) __attribute__ ((aligned, (x)))
8188 #define ALIGN_MAX __attribute__ ((aligned))
8189 
8191 //#define likely(x) __builtin_expect (!!(x), 1)
8192 //#define unlikely(x) __builtin_expect (!!(x), 0)
8193 
8194 #else
8195 #define UNUSED
8196 #define DEPRECATED
8197 #define PACKED
8198 #define CLEANUP
8199 #define FALLTHRU
8200 #define AINLINE
8201 #define NOINLINE
8202 #define PURE
8203 #define CONST
8204 #define NORETURN
8205 #define AMALLOC
8206 #define MUST_CHECK
8207 #define USED
8208 #define ALIGN(X)
8209 #define ALIGN_MAX
8210 #define likely(x) (x)
8211 #define unlikely(x) (x)
8212 #endif
8213 
8214 #endif // _libsheepyH
8215 // vim: set expandtab ts=2 sw=2:
char * iAppendCharS(char **string1, char c) MUST_CHECK
append char to string
Definition: libsheepy.c:7329
char * makeValidUTF8(const char *utf8) MUST_CHECK
make valid UTF-8 encoded string
Definition: libsheepy.c:46593
const char * findNextUTF8(const char *string, size_t utf8Size, const char *utf8) MUST_CHECK
find next UTF-8 code point even not at the start of a code point
Definition: libsheepy.c:46099
char * iExpandHome(char **path) MUST_CHECK
expands ~/ ($HOME) or ~USER
Definition: libsheepy.c:2638
char * iNormalizePath(char **path) MUST_CHECK
normalize path
Definition: libsheepy.c:3155
char * iAppendS(char **string1, const char *string2) MUST_CHECK
append strings
Definition: libsheepy.c:7285
bool eqS(const char *string1, const char *string2) MUST_CHECK
string Equal compare string1 to string2
Definition: libsheepy.c:9067
char ** icExtractSCharUTF8(const char *string, const char *delim1, char delim2) MUST_CHECK
char * quoteS(const char *s, char delim) MUST_CHECK
add backslash &#39;\&#39; before delim(&#39;\&#39;&#39; or &#39;"&#39;) and backslash the backslashes in the result avoid splitti...
Definition: libsheepy.c:9850
char * setUTF8(char *string, int64_t index, rune c) MUST_CHECK
set UTF8 encoded string
Definition: libsheepy.c:48598
#define MUST_CHECK
Definition: libsheepy.h:8206
char * s
char * appendCharS(const char *string1, char c) MUST_CHECK
append char to string when c is 0 the result is string1
Definition: libsheepy.c:7209
int writeFileS(const char *filePath, const char *string) MUST_CHECK
write string to file
Definition: libsheepy.c:4883
char ** btrace(void)
generate backtrace the program has to be linked the -rdynamic option for btrace to work btrace can ba...
Definition: libsheepy.c:55472
char ** listEmptySF(void) MUST_CHECK
list Empty String Function
Definition: libsheepy.c:50305
char * bGetCurrentDate(char *dst) MUST_CHECK
Definition: libsheepy.c:2121
size_t len
char ** splitS(const char *string, const char *delim) MUST_CHECK
Definition: libsheepy.c:51342
char * readLine(FILE *fp) MUST_CHECK
readLine from file stream the fist new line is converted to 0
Definition: libsheepy.c:6493
char * iEllipsisStartCharS(char **string, size_t targetLength, char ellipsisChar) MUST_CHECK
ellipsis start string
Definition: libsheepy.c:12366
bool isWritable(const char *path) MUST_CHECK
is path writable
Definition: libsheepy.c:1934
size_t listLengthS(char **list) MUST_CHECK
list Length String return number of elements until the first NULL element
Definition: libsheepy.c:50820
char ** readDirAll(const char *dirPath) MUST_CHECK
list files in a directory and sort the list
Definition: libsheepy.c:5392
void loghex(const void *buf, size_t len)
print buffer as hexadecimal string
Definition: libsheepy.c:6624
char * sliceUTF8(const char *string, int64_t start, int64_t end) MUST_CHECK
slice UTF8 encoded String return new string which is the string between start and end negative indexe...
Definition: libsheepy.c:48641
char * setS(char *string, int64_t index, char c) MUST_CHECK
set string
Definition: libsheepy.c:13898
bool eqIS(const char *string1, const char *string2, int64_t index) MUST_CHECK
string Index Equal compare string1 at index to string2 when string2 is empty, the result is false ...
Definition: libsheepy.c:9107
void ** listEmptyF(void) MUST_CHECK
list Empty Function
Definition: libsheepy.c:55649
char * iStripCtrlS(char **string) MUST_CHECK
remove terminal control char from string
Definition: libsheepy.c:9553
bool listIsBlankS(char **list) MUST_CHECK
list Is Empty String
Definition: libsheepy.c:50370
char * bLDelS(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK
buffer size delete string
Definition: libsheepy.c:15553
char * ellipsisStartS(const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK
ellipsis start string
Definition: libsheepy.c:12126
char ** listFromCArrayS(const char **array, size_t size) MUST_CHECK
list From Const Array String
Definition: libsheepy.c:50465
char * iAppendNFreeS(char **string1, char *string2) MUST_CHECK
append and free strings
Definition: libsheepy.c:7368
ssize_t padStartLenS(const char *string, size_t targetLength, const char *padString) MUST_CHECK
length of string after padStart
Definition: libsheepy.c:13378
char * bLowerS(char *string) MUST_CHECK
buffer lower case String
Definition: libsheepy.c:11220
ssize_t countS(const char *s, const char *needle) MUST_CHECK
count String count number of (non-overlapping) occurrences of a substring
Definition: libsheepy.c:9230
char * findCharS(const char *string, char c) MUST_CHECK
Definition: libsheepy.c:15799
char * strLCatUTF8(char *dst, size_t dstSize, const char *src) MUST_CHECK
strLCatUTF8 - concatenate two UTF-8 encoded strings
Definition: libsheepy.c:46978
void freeManySF(char *paramType,...)
free Many String
Definition: libsheepy.c:6526
int randomUrandomOpen(void) MUST_CHECK
open /dev/urandom in libsheepy
Definition: libsheepy.c:5895
ssize_t listBinarySearchS(char **list, const char *string) MUST_CHECK
list binary search string
Definition: libsheepy.c:54861
int ringInit(void *ring, int maxCount)
list Sort duplicate list and sort
Definition: libsheepy.c:57082
char * bStripCtrlS(char *string) MUST_CHECK
remove terminal control char from string
Definition: libsheepy.c:9581
char * bUniqS(char *string, char c) MUST_CHECK
buffer uniq String
Definition: libsheepy.c:11682
void ** iListSlice(void ***list, int64_t start, int64_t end) MUST_CHECK
list Slice return list with elements from start and end in list negative indexes are allowed ...
Definition: libsheepy.c:56441
void ** iListInsert(void ***list, int64_t index, void **toInsert) MUST_CHECK
list Insert
Definition: libsheepy.c:56602
char * bTimeToYMDS(char *dst, const time_t t) MUST_CHECK
Definition: libsheepy.c:2091
char * emptySF(void) MUST_CHECK
empty String Function
Definition: libsheepy.c:50188
char * injectS(const char *string, int64_t index, char toInject) MUST_CHECK
inject a char in string at index
Definition: libsheepy.c:15061
char * casefoldUTF8(const char *utf8) MUST_CHECK
casefold UTF-8 encoded string
Definition: libsheepy.c:48294
bool isNumber(const char *string) MUST_CHECK
is Number (integer or float) String
Definition: libsheepy.c:10749
bool eqICharS(const char *string1, char c, int64_t index) MUST_CHECK
Definition: libsheepy.c:9142
bool getLogStdout(void) MUST_CHECK
get stdout state, when TRUE (default) all logs are printed to stdout
Definition: libsheepy.c:1149
char ** iListSliceS(char ***list, int64_t start, int64_t end) MUST_CHECK
list Slice String return list with elements from start and end in list negative indexes are allowed ...
Definition: libsheepy.c:52623
void btraceEnable(void)
Definition: libsheepy.c:55441
char ** iListDelS(char ***list, int64_t start, int64_t end) MUST_CHECK
list Delete String return list without elements from start and end in list negative indexes are allow...
Definition: libsheepy.c:53512
bool icListEqC1S(const char **list1, char **list2) MUST_CHECK
ignore case const(list1) list Equal String compare each element of list1 and list2 ...
Definition: libsheepy.c:55046
mode_t getUmask(void) MUST_CHECK
get umask
Definition: libsheepy.c:5433
char * uniqUTF8(const char *string, const char *code) MUST_CHECK
uniq UTF-8 String duplicate string
Definition: libsheepy.c:48352
char ** iListInsertS(char ***list, int64_t index, char **toInsert) MUST_CHECK
list Insert string
Definition: libsheepy.c:53060
char * bLEscapeS(char *dest, size_t destSize, const char *s, char delim) MUST_CHECK
escape string according the json specification (RFC 8259) if there is in the string, the backslash is escaped and it will be parsed as the string &#39;&#39; be the json parsers the unicode characters should be converted to UTF8 codepoints instead of using the result can be included in a json string and the parsing will be correct
Definition: libsheepy.c:10205
char * bicUniqUTF8(char *string, char c) MUST_CHECK
char * iSwapS(char **string, int64_t index1, int64_t index2) MUST_CHECK
swap characters in string
Definition: libsheepy.c:13986
char * listGetS(char **list, int64_t index) MUST_CHECK
list Get String duplicate string at given index index can be negative
Definition: libsheepy.c:50967
void setSoftwareRandom(void)
use software random numbers works on all cpu architectures the default random function is software ...
Definition: libsheepy.c:5869
char ** splitChar(const char *string, char delim) MUST_CHECK
Definition: libsheepy.c:51388
char * bLPadStartCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char padChar) MUST_CHECK
pad start string
Definition: libsheepy.c:13332
bool appendCText(const char *filePath, const char **list) MUST_CHECK
append const list to filePath
Definition: libsheepy.c:54389
ssize_t listBinarySearchCharS(char **list, char c) MUST_CHECK
Definition: libsheepy.c:54884
char * tokS(char *s, const char *delim, char **saveptr) MUST_CHECK
token in String
Definition: libsheepy.c:15996
void ** listAdd(void **list1, void **list2) MUST_CHECK
list Add add list1 and list2 in a new list
Definition: libsheepy.c:56308
rune toupperUTF8(rune c) MUST_CHECK
rune toupper UTF8
Definition: libsheepy.c:47854
i64 ringPrepend(void *ring)
prepend element to ring (only decreases head) use ringFirst to access the element ...
Definition: libsheepy.c:57249
char * bLicReplaceUTF8(char *s, size_t sSize, const char *olds, const char *news, size_t max) MUST_CHECK
char * bQuoteS(char *dest, const char *s, char delim) MUST_CHECK
add backslash &#39;\&#39; before delim(&#39;\&#39;&#39; or &#39;"&#39;) and backslash the backslashes in the result avoid splitti...
Definition: libsheepy.c:9914
char * icReplaceCharSUTF8(const char *s, char olds, const char *news, size_t max) MUST_CHECK
char ** readText(const char *filePath) MUST_CHECK
return text from filePath in a list new line characters are removed
Definition: libsheepy.c:54122
bool writeCStream(FILE *fp, const char **list) MUST_CHECK
write const list to stream
Definition: libsheepy.c:54328
ssize_t icListIndexOfCS(const char **list, const char *string) MUST_CHECK
ignore case and return index of string in const list
Definition: libsheepy.c:55200
void cleanUpCharFree(char **val)
Definition: libsheepy.c:919
void keepAnsiColorsInLog(bool state)
enable/disable ansi color codes in logs
Definition: libsheepy.c:1194
ssize_t listIndexOfCharS(char **list, char c) MUST_CHECK
Definition: libsheepy.c:54835
void setDefaultProgName(void)
set default program name
Definition: libsheepy.c:1773
char * bSliceS(char *string, int64_t start, int64_t end) MUST_CHECK
buffer slice String return string which is the string between start and end negative indexes are allo...
Definition: libsheepy.c:14286
bool icHasS(const char *string, const char *needle) MUST_CHECK
ignore case has String
Definition: libsheepy.c:15955
uint64_t randomChoice(uint64_t range) MUST_CHECK
return a random value between 0 and range 0<=value<range call randomUrandomOpen before this calling f...
Definition: libsheepy.c:5991
bool icEqCharS(char c, const char *string2) MUST_CHECK
Definition: libsheepy.c:9292
char ** icListSortUTF8(char **list) MUST_CHECK
ignore case list Sort UTF8 encoded String duplicate list and sort
Definition: libsheepy.c:49903
char * iEllipsisEndCharS(char **string, size_t targetLength, char ellipsisChar) MUST_CHECK
ellipsis end string
Definition: libsheepy.c:12802
char * replaceS(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK
replace String the original remains unchanged duplicate s the olds string is replaced with the news s...
Definition: libsheepy.c:7731
char * bUpperUTF8(char *string) MUST_CHECK
char ** iListReverseS(char ***list) MUST_CHECK
list Reverse String reverse list, the last element is the first element of the list ...
Definition: libsheepy.c:52051
char * findS(const char *string, const char *needle) MUST_CHECK
find String
Definition: libsheepy.c:15790
bool eqCharS(char c, const char *string2) MUST_CHECK
Definition: libsheepy.c:9076
char * delElemS(const char *string, int64_t index) MUST_CHECK
delete element/character string
Definition: libsheepy.c:15617
char * iInsertS(char **string, int64_t index, const char *toInsert) MUST_CHECK
insert string in string at index
Definition: libsheepy.c:14756
char * cropS(char *string, int64_t start, int64_t end) MUST_CHECK
Crop String return a new string with characters from start and end in string and delete characters fr...
Definition: libsheepy.c:14430
char * listPopS(char ***list) MUST_CHECK
list Pop String return last string from list and remove last element from the list ...
Definition: libsheepy.c:50602
ssize_t icListIndexOfCharS(char **list, char c) MUST_CHECK
Definition: libsheepy.c:55222
char * ellipsisEndCharS(const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK
ellipsis end string
Definition: libsheepy.c:12757
int rmAll(const char *path) MUST_CHECK
remove all delete recursively files and directories
Definition: libsheepy.c:5510
ssize_t listIntIndexS(char **list, int64_t index) MUST_CHECK
list int to index String index can be negative
Definition: libsheepy.c:50892
int enableCoreDump(void) MUST_CHECK
enable core dump
Definition: libsheepy.c:1720
char * strLCat(char *restrict dst, size_t dstSize, const char *restrict src) MUST_CHECK
strLCat - concatenate two strings
Definition: libsheepy.c:6897
bool fiberAdd(void *ctx, int thisSlot, fiberFT func)
add new fiber
Definition: libsheepy.c:57321
char * bPadStartS(char *dest, const char *string, size_t targetLength, const char *padString) MUST_CHECK
pad start string
Definition: libsheepy.c:13061
const uint8_t codeSzUTF8[256]
Definition: libsheepy.c:31675
char * expandHome(const char *path) MUST_CHECK
expands ~/ ($HOME) or ~USER duplicate and expand path.
Definition: libsheepy.c:2443
void ** listSlice(void **list, int64_t start, int64_t end) MUST_CHECK
list Slice
Definition: libsheepy.c:56370
char * listGetCS(const char **list, int64_t index) MUST_CHECK
const list Get String duplicate string at given index index can be negative
Definition: libsheepy.c:51036
char ** walkDir(const char *dirPath) MUST_CHECK
list all files in a directory recursively and sort the list
Definition: libsheepy.c:5103
char ** listSwapS(char **list, int64_t index1, int64_t index2) MUST_CHECK
swap elements in list
Definition: libsheepy.c:51195
char ** icExtractUTF8(const char *string, const char *delim1, const char *delim2) MUST_CHECK
char * relPath(const char *path, const char *start) MUST_CHECK
relative path
Definition: libsheepy.c:3472
char * randomS(uint64_t length) MUST_CHECK
random string
Definition: libsheepy.c:6020
char * bLicReplaceS(char *s, size_t sSize, const char *olds, const char *news, size_t max) MUST_CHECK
buffer size ignore case replace String the olds string is replaced with the news string max times in ...
Definition: libsheepy.c:8742
char * iicReplaceManySF(char **string, char *paramType,...) MUST_CHECK
in place ignore case replace Many Strings the olds string is replaced with the news string max times ...
Definition: libsheepy.c:8908
char * prependCharS(const char *string1, char c) MUST_CHECK
prepend char to string
Definition: libsheepy.c:7526
char * timeToYMDS(const time_t t) MUST_CHECK
time To Year-Month-Day Hour:Minute:Second String convert unix time to string
Definition: libsheepy.c:2082
void setMaxLogLevel(int logLevel)
set max log level logs above logMaxLevel are skipped
Definition: libsheepy.c:1043
char ** listUniqS(char **list) MUST_CHECK
Uniquify elements of list duplicate list each elements are unique in the new list.
Definition: libsheepy.c:54902
char * prependSChar(char c, const char *string2) MUST_CHECK
prepend string to char
Definition: libsheepy.c:7541
char * formatS(const char *fmt,...) MUST_CHECK
format string allocate and format string using asprintf
Definition: libsheepy.c:7092
char ** iListCropS(char ***list, int64_t start, int64_t end) MUST_CHECK
list Crop String return a new list with elements from start and end in list and delete elements from ...
Definition: libsheepy.c:52799
char * insertUTF8(const char *string, int64_t index, const char *toInsert) MUST_CHECK
insert string in UTF8 encoded string at index
Definition: libsheepy.c:48956
char * bLTimeToS(char *dst, size_t dstSize, const time_t t) MUST_CHECK
Definition: libsheepy.c:2065
bool icStartsWithS(const char *string1, const char *string2) MUST_CHECK
ignore case starts With String compare start of string1 with string2
Definition: libsheepy.c:9374
bool icListHasUTF8(char **list, const char *string) MUST_CHECK
ignore case and return true when list has UTF8 encoded string
Definition: libsheepy.c:49994
char nibbleToHex(u8 n) MUST_CHECK
convert number between 0 and 15 to hexadecimal character &#39;0&#39; to &#39;F&#39;
Definition: libsheepy.c:10301
bool icListHasS(char **list, const char *string) MUST_CHECK
ignore case and return true when list has string
Definition: libsheepy.c:55108
char * strNCpy(char *restrict dst, const char *restrict src, size_t srcSize) MUST_CHECK
strNCpy - copy src to dst
Definition: libsheepy.c:6796
char * strCat(char *restrict dst, const char *restrict src) MUST_CHECK
strCat - concatenate two strings
Definition: libsheepy.c:6848
void ** listAppend(void ***list1, void **list2) MUST_CHECK
list Append
Definition: libsheepy.c:56240
char * bEllipsisStartCharS(char *dest, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK
ellipsis start string
Definition: libsheepy.c:12413
jmp_buf tryJumpBuffers[maxTryThrowCount]
setjmp buffers for try/throw,throwV macros
Definition: libsheepy.c:872
void ** iListDel(void ***list, int64_t start, int64_t end) MUST_CHECK
list Delete return list without elements from start and end in list negative indexes are allowed ...
Definition: libsheepy.c:56761
const bool FALSE
type bool false (glibc true is not bool), for use in generics
Definition: libsheepy.c:864
int64_t ptr2IdxUTF8(const char *utf8, const char *pos) MUST_CHECK
pointer to code point index UTF8 encoded string
Definition: libsheepy.c:46371
char * delUTF8(const char *string, int64_t start, int64_t end) MUST_CHECK
delete UTF8 encoded string
Definition: libsheepy.c:49424
void ** listPush(void ***list, void *s) MUST_CHECK
list Push
Definition: libsheepy.c:55790
size_t quoteLenS(const char *s, char delim) MUST_CHECK
return the length of the escaped string (without the terminating \0)
Definition: libsheepy.c:10007
char * iicUniqS(char **string, char c) MUST_CHECK
in place ignore case uniq String
Definition: libsheepy.c:11774
char * bLSwapS(char *string, size_t size, int64_t index1, int64_t index2) MUST_CHECK
swap characters in string
Definition: libsheepy.c:14087
char * iicReplaceManyUTF8F(char **s, char *paramType,...) MUST_CHECK
fiberLT L
running fibers
Definition: libsheepy.h:6846
bool isReadable(const char *path) MUST_CHECK
is path readable
Definition: libsheepy.c:1914
char * bInsertS(char *string, int64_t index, const char *toInsert) MUST_CHECK
buffer insert string in string at index
Definition: libsheepy.c:14917
char * iListGetS(char **list, int64_t index) MUST_CHECK
list Get String index can be negative
Definition: libsheepy.c:51001
size_t bLLenUTF8(const char *s, size_t maxSize) MUST_CHECK
buffer character length of UTF-8 string
Definition: libsheepy.c:16095
void(* fiberFT)(int)
fiber function type
Definition: libsheepy.h:6874
char * strCpy(char *restrict dst, const char *restrict src) MUST_CHECK
strCpy - copy src to dst
Definition: libsheepy.c:6771
bool icListHasCharCS(const char **list, char c) MUST_CHECK
Definition: libsheepy.c:55148
char ** listReverseS(char **list) MUST_CHECK
list Reverse String duplicate and reverse list, the last element is the first element of the new list...
Definition: libsheepy.c:52015
char ** extractCharSS(const char *string, char delim1, const char *delim2) MUST_CHECK
Definition: libsheepy.c:51805
char * icUniqS(const char *string, char c) MUST_CHECK
ignore case uniq String duplicate string
Definition: libsheepy.c:11726
char * listDequeueS(char ***list) MUST_CHECK
list Dequeue String return first string from list and remove it from the list
Definition: libsheepy.c:50746
char * appendSChar(char c, const char *string2) MUST_CHECK
append string to char
Definition: libsheepy.c:7245
void * bReadStreamToS(FILE *fp, void *dst) MUST_CHECK
buffer read file to string
Definition: libsheepy.c:4579
ssize_t bReadFile(const char *filePath, void *buffer) MUST_CHECK
buffer read file to buffer
Definition: libsheepy.c:4782
bool appendText(const char *filePath, char **list) MUST_CHECK
append list to filePath
Definition: libsheepy.c:54352
bool fileExists(const char *filePath) MUST_CHECK
detect files and directories
Definition: libsheepy.c:4321
char * iicUniqUTF8(char **string, const char *code) MUST_CHECK
char * bReplaceS(char *s, const char *olds, const char *news, size_t max) MUST_CHECK
buffer replace String the olds string is replaced with the news string max times in the result 0 for ...
Definition: libsheepy.c:8004
char * iDelUTF8(char **string, int64_t start, int64_t end) MUST_CHECK
delete UTF8 encoded string
Definition: libsheepy.c:49499
bool icStartsWithUTF8(const char *string1, const char *string2) MUST_CHECK
ignore case starts With UTF8 encoded String compare start of string1 with string2 ...
Definition: libsheepy.c:47419
char * icFindS(const char *string, const char *needle) MUST_CHECK
ignore case Find String
Definition: libsheepy.c:15888
char * bLAppendManySF(char *string, size_t stringSize, const char *paramType,...) MUST_CHECK
buffer size append many strings
Definition: libsheepy.c:7466
char ** listAppendS(char ***list1, char **list2) MUST_CHECK
list Append String Append list2 at the end of list1
Definition: libsheepy.c:52116
char * bTimeToS(char *dst, const time_t t) MUST_CHECK
Definition: libsheepy.c:2057
void * bLReadStreamToS(FILE *fp, void *dst, size_t dstSize) MUST_CHECK
buffer size read file to string
Definition: libsheepy.c:4678
char * iPrependCharS(char **string1, char c) MUST_CHECK
prepend char to string
Definition: libsheepy.c:7591
void * readFileToS(const char *filePath) MUST_CHECK
read file to string
Definition: libsheepy.c:4427
void cleanUpListFree(char ***val)
Definition: libsheepy.c:925
bool icEqUTF8Char(const char *string1, char c) MUST_CHECK
Definition: libsheepy.c:47371
char ** iListCompactS(char ***list) MUST_CHECK
remove empty strings from list
Definition: libsheepy.c:55407
char * bLCEscapeS(char *dest, size_t destSize, const char *S) MUST_CHECK
escape string to become a valid C source string control characters, backslash and double quotes are e...
Definition: libsheepy.c:10549
baset * b
char * bRandomAlphaNumS(char *dst, size_t dstSize) MUST_CHECK
buffer random alpha numerical string
Definition: libsheepy.c:6192
char ** icExtractS(const char *string, const char *delim1, const char *delim2) MUST_CHECK
ignore case extract string between delim1 and delim2 strings return list
Definition: libsheepy.c:51838
char ** iListDupS(char **list) MUST_CHECK
list Duplicate String
Definition: libsheepy.c:51980
char * padStartCharS(const char *string, size_t targetLength, char padChar) MUST_CHECK
pad start string
Definition: libsheepy.c:13183
char * stripColorsS(const char *string) MUST_CHECK
remove ansi colors from string
Definition: libsheepy.c:9609
char * joinS(char **list, const char *delim) MUST_CHECK
Definition: libsheepy.c:51589
rune code2RuneUTF8(const char *code) MUST_CHECK
UTF-8 code point to rune.
Definition: libsheepy.c:47550
char * bicReplaceUTF8(char *s, const char *olds, const char *news, size_t max) MUST_CHECK
int nanoSleepF(uint64_t time) MUST_CHECK
nanosleep
Definition: libsheepy.c:57427
char ** iListRemoveElemS(char ***list, int64_t index) MUST_CHECK
list Remove Element String return list without the element at index the element is removed without be...
Definition: libsheepy.c:53785
char * replaceManySF(const char *paramType,...) MUST_CHECK
replace Many Strings the original remains unchanged duplicate s the olds string is replaced with the ...
Definition: libsheepy.c:8202
size_t escapeLenS(const char *s, char delim) MUST_CHECK
return the length of the escaped string (without the terminating \0)
Definition: libsheepy.c:10276
char * normalizePath(const char *path) MUST_CHECK
normalize path
Definition: libsheepy.c:3057
size_t sizeS(const char *string) MUST_CHECK
string buffer size
Definition: libsheepy.c:11066
size_t cEscapeLenS(const char *s) MUST_CHECK
return the length of the escaped string (without the terminating \0)
Definition: libsheepy.c:10693
int shRename(const char *src, const char *dst) MUST_CHECK
rename file
Definition: libsheepy.c:5808
char ** listPrependS(char ***list, const char *s) MUST_CHECK
list Prepend String append s at the beginning of the list when list is NULL, a new list with one elem...
Definition: libsheepy.c:50641
void * bReadFileToS(const char *filePath, void *dst) MUST_CHECK
buffer read file to string
Definition: libsheepy.c:4530
char * bSliceUTF8(char *string, int64_t start, int64_t end) MUST_CHECK
buffer slice UTF8 encoded String return string which is the string between start and end negative ind...
Definition: libsheepy.c:48791
ssize_t icListIndexOfS(char **list, const char *string) MUST_CHECK
ignore case and return index of string in list
Definition: libsheepy.c:55166
bool bLIsUTF8(const char *string, size_t stringSize) MUST_CHECK
buffer length is UTF-8 string
Definition: libsheepy.c:16178
const char * getRealProgPath(void) MUST_CHECK
get real program path The first call allocates libSheepyRealProgPath, it is freed with freeRealProgPa...
Definition: libsheepy.c:1812
char * iPadStartS(char **string, size_t targetLength, const char *padString) MUST_CHECK
pad start string
Definition: libsheepy.c:13009
char * listCropElemS(char **list, int64_t index) MUST_CHECK
list Crop Element String return element at index and delete element at index in the original list neg...
Definition: libsheepy.c:52879
bool writeStream(FILE *fp, char **list) MUST_CHECK
write list to stream
Definition: libsheepy.c:54304
bool icListEqCCS(const char **list1, const char **list2) MUST_CHECK
ignore case const(list1 and 2) list Equal String compare each element of list1 and list2 ...
Definition: libsheepy.c:55076
char * iicReplaceCharSUTF8(char **s, char olds, const char *news, size_t max) MUST_CHECK
char * bLRepeatS(char *dest, size_t destSize, const char *string, size_t count) MUST_CHECK
repeat string count times
Definition: libsheepy.c:11996
char * bUniqUTF8(char *string, const char *code) MUST_CHECK
buffer uniq String
Definition: libsheepy.c:48463
char * iInsertUTF8(char **string, int64_t index, const char *toInsert) MUST_CHECK
insert string in UTF8 encoded string at index
Definition: libsheepy.c:49110
void setLogSymbols(int mode)
set log symbols
Definition: libsheepy.c:1012
char ** icSplitChar(const char *string, char delim) MUST_CHECK
Definition: libsheepy.c:51501
char ** iListSetS(char **list, int64_t index, char *s) MUST_CHECK
list Set String store string at given index index can be negative
Definition: libsheepy.c:51158
void _pLog(int, const char *, const char *, int, const char *,...)
Definition: libsheepy.c:1210
void initLibsheepyF(const char *progPath, initLibsheepyObjectP initF)
initialize libsheepy (optional, for debug)
Definition: libsheepy.c:1579
ssize_t listStrLengthS(char **list) MUST_CHECK
list String Length String
Definition: libsheepy.c:50865
char ** iListDelElemS(char ***list, int64_t index) MUST_CHECK
list Delete Element String return list without the element at index negative indexes are allowed ...
Definition: libsheepy.c:53725
bool icEqCharUTF8(char c, const char *string2) MUST_CHECK
Definition: libsheepy.c:47357
int rune
Definition: libsheepy.h:2312
bool fiberPrepend(void *ctx, int thisSlot, fiberFT func)
add new fiber and start immediately after next yield
Definition: libsheepy.c:57344
char * iDelS(char **string, int64_t start, int64_t end) MUST_CHECK
delete string
Definition: libsheepy.c:15415
char * iReplaceCharSS(char **s, char olds, const char *news, size_t max) MUST_CHECK
Definition: libsheepy.c:7971
char * bLSliceUTF8(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK
buffer size slice UTF8 encoded String return string which is the string between start and end negativ...
Definition: libsheepy.c:48862
char * iStripColorsS(char **string) MUST_CHECK
remove ansi colors from string
Definition: libsheepy.c:9690
char ** extractSCharS(const char *string, const char *delim1, char delim2) MUST_CHECK
Definition: libsheepy.c:51811
uint64_t logMask
variable to control which group logs to show, all logs are enabled by default (0xFFFFFFFFFFFFFFFF) ...
Definition: libsheepy.c:974
char ** listCreateSF(const char *paramType,...) MUST_CHECK
list Create String Function create a list from the list of parameters used from the listCreateS(...
Definition: libsheepy.c:50395
char * insertNFreeS(const char *string, int64_t index, char *toInsert) MUST_CHECK
insert string in string at index and free toInsert when successful
Definition: libsheepy.c:14678
char * repeatCharS(char c, size_t count) MUST_CHECK
repeat char count times
Definition: libsheepy.c:12036
ssize_t joinLength(char **list, const char *delim) MUST_CHECK
join Length list length after joined with delimiter
Definition: libsheepy.c:51519
char ** execOut(const char *cmd) MUST_CHECK
execute command return stdout from cmd
Definition: libsheepy.c:54426
char * bLReplaceS(char *s, size_t sSize, const char *olds, const char *news, size_t max) MUST_CHECK
buffer size replace String the olds string is replaced with the news string max times in the result 0...
Definition: libsheepy.c:8097
bool eqICharUTF8(const char *string1, char c, int64_t index) MUST_CHECK
Definition: libsheepy.c:47322
char * endlink(const char *path) MUST_CHECK
end link
Definition: libsheepy.c:4215
ssize_t listIndexOfCharCS(const char **list, char c) MUST_CHECK
Definition: libsheepy.c:54841
#define staticArrayT(typeName, element, MAXCOUNT)
declares type for staticArray or ring
Definition: libsheepy.h:6124
char ** iListPrependS(char ***list, char *s) MUST_CHECK
list Prepend String append s pointer at the beginning of the list when list is NULL, a new list with one element is returned when list and s are NULL return list with 2 NULL elements when s is NULL, the operation is canceled
Definition: libsheepy.c:50700
char * bLEllipsisEndS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK
ellipsis end string
Definition: libsheepy.c:12699
char * shReadlink(const char *path) MUST_CHECK
sheepy read link
Definition: libsheepy.c:4153
int getLogSymbols(void) MUST_CHECK
get current log symbols
Definition: libsheepy.c:996
char * array[]
ssize_t icIndexOfUTF8(const char *string, const char *needle) MUST_CHECK
bool listHasCharS(char **list, char c) MUST_CHECK
Definition: libsheepy.c:54755
int64_t parseI64Char(char c) MUST_CHECK
Definition: libsheepy.c:10897
char * replaceSCharS(const char *s, const char *olds, char news, size_t max) MUST_CHECK
Definition: libsheepy.c:7811
void * bLReadFileToS(const char *filePath, void *dst, size_t dstSize) MUST_CHECK
buffer size read file to string
Definition: libsheepy.c:4621
ssize_t fileSizeFP(FILE *fp) MUST_CHECK
get file size from file pointer
Definition: libsheepy.c:4401
char * bLDelElemS(char *string, size_t stringSize, int64_t index) MUST_CHECK
buffer size delete element/character string
Definition: libsheepy.c:15748
char ** listCropS(char **list, int64_t start, int64_t end) MUST_CHECK
list Crop String return a new list with elements from start and end in list and delete elements from ...
Definition: libsheepy.c:52717
char ** icExtractCharCharS(const char *string, char delim1, char delim2) MUST_CHECK
Definition: libsheepy.c:51890
void ** iListEmptyF(void ***list) MUST_CHECK
list Empty Function
Definition: libsheepy.c:55668
ssize_t countCharS(const char *s, char c) MUST_CHECK
Definition: libsheepy.c:9254
char * randomAlphaNumS(uint64_t length) MUST_CHECK
random alpha numerical string
Definition: libsheepy.c:6132
ssize_t padEndLenS(const char *string, size_t targetLength, const char *padString) MUST_CHECK
length of string after padEnd
Definition: libsheepy.c:13847
char * bTrimS(char *string) MUST_CHECK
buffer trim String
Definition: libsheepy.c:11345
char ** listDelElemS(char **list, int64_t index) MUST_CHECK
list Delete Element String return new list without the element at index negative indexes are allowed ...
Definition: libsheepy.c:53670
char * bReplaceManySF(char *s, char *paramType,...) MUST_CHECK
buffer replace Many Strings the olds string is replaced with the news string max times in the result ...
Definition: libsheepy.c:8317
char cropElemS(char *string, int64_t index) MUST_CHECK
Definition: libsheepy.c:14553
char * rTrimS(const char *string) MUST_CHECK
right trim String duplicate string
Definition: libsheepy.c:11492
#define range(index, maxCount)
range loop ;size_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a decl...
Definition: libsheepy.h:2772
char * bEllipsisEndS(char *dest, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK
ellipsis end string
Definition: libsheepy.c:12644
void ** listSet(void **list, int64_t index, void *s) MUST_CHECK
list Set
Definition: libsheepy.c:56066
void btraceDisable(void)
Definition: libsheepy.c:55446
uint64_t parseHex(const char *string) MUST_CHECK
parse hexadecimal number in a string
Definition: libsheepy.c:10944
void closeLogFiles(void)
close logfiles opened with setLogFile
Definition: libsheepy.c:1081
uint8_t runeLenUTF8(rune r) MUST_CHECK
rune length as UTF-8 code point
Definition: libsheepy.c:47670
char * bRandomS(char *dst, size_t length) MUST_CHECK
buffer random string
Definition: libsheepy.c:6080
char * bLDirname(char *path, size_t pathSize) MUST_CHECK
buffer size dirname
Definition: libsheepy.c:2306
char ** listSetCharS(char **list, int64_t index, char c) MUST_CHECK
Definition: libsheepy.c:51134
char * strNCat(char *restrict dst, const char *restrict src, size_t srcLen) MUST_CHECK
strNCat - concatenate two strings
Definition: libsheepy.c:6872
char ** iListShiftS(char ***list1, char **list2) MUST_CHECK
in place list Shift String Append list2 at the start of list1 by copying the pointers from list2 to l...
Definition: libsheepy.c:52330
void setLogStdout(bool state)
enable/disable printing logs to stdout
Definition: libsheepy.c:1160
bool equalModificationTimes(const char *path1, const char *path2) MUST_CHECK
compare modification times for path1 and path2
Definition: libsheepy.c:1979
void scheduler(void)
fiber usage
Definition: libsheepy.c:57358
bool isInt(const char *string) MUST_CHECK
is Integer String
Definition: libsheepy.c:10811
staticArray type definition
Definition: libsheepy.h:6107
char * bLGetCurrentDate(char *dst, size_t dstSize) MUST_CHECK
Definition: libsheepy.c:2132
char * iSliceS(char **string, int64_t start, int64_t end) MUST_CHECK
slice String return string which is the string between start and end negative indexes are allowed ...
Definition: libsheepy.c:14213
bool icEqUTF8(const char *string1, const char *string2) MUST_CHECK
ignore case UTF8 encoded string Equal compare string1 to string2
Definition: libsheepy.c:47343
char * bLRepeatCharS(char *dest, size_t destSize, char c, size_t count) MUST_CHECK
repeat char count times
Definition: libsheepy.c:12076
char * timeToS(const time_t t) MUST_CHECK
time To String convert unix time to string (ctime is not used here because it adds at the end of th...
Definition: libsheepy.c:2048
char * getCwd(void) MUST_CHECK
get current working directory
Definition: libsheepy.c:4054
char ** walkDirDir(const char *dirPath) MUST_CHECK
list all directories in a directory recursively and sort the list
Definition: libsheepy.c:5166
char * icReplaceCharSS(const char *s, char olds, const char *news, size_t max) MUST_CHECK
Definition: libsheepy.c:8503
char * bLEllipsisStartS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK
ellipsis start string
Definition: libsheepy.c:12265
bool hasS(const char *string, const char *needle) MUST_CHECK
has String
Definition: libsheepy.c:15851
char * dupS(const char *string) MUST_CHECK
duplicate string
Definition: libsheepy.c:6548
char * bPadEndS(char *dest, const char *string, size_t targetLength, const char *padString) MUST_CHECK
pad end string
Definition: libsheepy.c:13527
char * bLMakeValidUTF8(char *dst, size_t dstSize, const char *utf8) MUST_CHECK
buffer destination size make valid UTF-8 encoded string
Definition: libsheepy.c:46773
char ** walkDirAll(const char *dirPath) MUST_CHECK
list all files and directories in a directory recursively and sort the list
Definition: libsheepy.c:5331
char * bLReadS(char *dst, size_t dstSize) MUST_CHECK
buffer read String read user input (one line) as a string
Definition: libsheepy.c:6297
void finalizeLibsheepyCharAtExit(void)
finalize libsheepy char at exit
Definition: libsheepy.c:1652
void logNFree(char *s)
log and free
Definition: libsheepy.c:6613
int getMaxLogLevel(void) MUST_CHECK
get current max log level
Definition: libsheepy.c:1028
char * strLCpy(char *restrict dst, size_t dstSize, const char *restrict src) MUST_CHECK
strLCpy - copy src to dst
Definition: libsheepy.c:6822
void ** listDup(void **list) MUST_CHECK
list Duplicate
Definition: libsheepy.c:56110
char * upperS(const char *string) MUST_CHECK
upper case String duplicate string
Definition: libsheepy.c:11083
char * bEllipsisStartS(char *dest, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK
ellipsis start string
Definition: libsheepy.c:12217
int64_t parseIntChar(char c) MUST_CHECK
Definition: libsheepy.c:10863
char * bEscapeS(char *dest, const char *s, char delim) MUST_CHECK
escape string according the json specification (RFC 8259) if there is in the string, the backslash is escaped and it will be parsed as the string &#39;&#39; be the json parsers the unicode characters should be converted to UTF8 codepoints instead of using the result can be included in a json string and the parsing will be correct
Definition: libsheepy.c:10134
char ** icSplitS(const char *string, const char *delim) MUST_CHECK
Definition: libsheepy.c:51455
char * delS(const char *string, int64_t start, int64_t end) MUST_CHECK
delete string
Definition: libsheepy.c:15345
uint64_t randomWordFromHW(void) MUST_CHECK
return random 64 bit unsigned integer from the cpu when the cpu doesn&#39;t have the random generator ins...
Definition: libsheepy.c:5959
char * icReplaceManySF(const char *paramType,...) MUST_CHECK
ignore case replace Many Strings the original remains unchanged duplicate s the olds string is replac...
Definition: libsheepy.c:8847
char ** iListInsertNFreeS(char ***list, int64_t index, char **toInsert) MUST_CHECK
list Insert string and free toInsert
Definition: libsheepy.c:53161
char ** listPrependCharS(char ***list, char c) MUST_CHECK
Definition: libsheepy.c:50677
bool icEqSChar(const char *string1, char c) MUST_CHECK
Definition: libsheepy.c:9302
void setLogMode(int mode)
set log mode LOG_VERBOSE, LOG_CONCISE, .
Definition: libsheepy.c:1107
char * iUpperS(char **string) MUST_CHECK
upper case String
Definition: libsheepy.c:11114
char ** listDupCS(const char **list) MUST_CHECK
const list Duplicate String
Definition: libsheepy.c:51940
time_t strToUnixTime(const char *date, const char *format) MUST_CHECK
convert date string to unix time
Definition: libsheepy.c:2018
const char * getProgPath(void) MUST_CHECK
get program path When initLibsheepy is called before this function, it returns the given program path...
Definition: libsheepy.c:1795
char * iDelElemS(char **string, int64_t index) MUST_CHECK
delete element/character string
Definition: libsheepy.c:15660
void cleanUpFileFree(FILE **val)
Definition: libsheepy.c:931
char * bicUniqS(char *string, char c) MUST_CHECK
ignore case buffer uniq String
Definition: libsheepy.c:11820
void ** iListReverse(void ***list) MUST_CHECK
list Reverse reverse list, the last element is the first element of the list
Definition: libsheepy.c:56182
#define i64
Definition: libsheepy.h:444
bool endsWithS(const char *string1, const char *string2) MUST_CHECK
ends With String compare end of string1 with string2
Definition: libsheepy.c:9185
const char * bPrevUTF8(const char *string, const char *utf8) MUST_CHECK
buffer previous UTF-8 code point
Definition: libsheepy.c:46161
bool listEqCCS(const char **list1, const char **list2) MUST_CHECK
const(list1 and 2) list Equal String compare each element of list1 and list2
Definition: libsheepy.c:54689
END_TEST FILE * fp
char * iTrimS(char **string) MUST_CHECK
trim String
Definition: libsheepy.c:11292
char * iEllipsisEndS(char **string, size_t targetLength, const char *ellipsisString) MUST_CHECK
ellipsis end string
Definition: libsheepy.c:12595
const bool TRUE
type bool true (glibc true is not bool), for use in generics
Definition: libsheepy.c:862
const char * bLNextUTF8(const char *string, size_t utf8Size, const char *utf8) MUST_CHECK
buffer length next UTF-8 code point
Definition: libsheepy.c:46067
char ** listDupS(char **list) MUST_CHECK
list Duplicate String
Definition: libsheepy.c:51906
char ** split(const char *string, const char *delim) MUST_CHECK
split string with delim string when updating this function, also update splitS (identical to split) r...
Definition: libsheepy.c:51294
rune tolowerUTF8(rune c) MUST_CHECK
rune tolower UTF8
Definition: libsheepy.c:48078
char * icReplaceUTF8(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK
ssize_t icIndexOfCharS(const char *string, char c) MUST_CHECK
Definition: libsheepy.c:15934
int(* shCmpt)(const void *a, const void *b)
Definition: libsheepy.h:3085
char * bGetHomePath(char *path) MUST_CHECK
copy home path to path
Definition: libsheepy.c:4000
char * ellipsisStartCharS(const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK
ellipsis start string
Definition: libsheepy.c:12319
char * upperUTF8(const char *string) MUST_CHECK
upper case UTF-8 encoded string duplicate string
Definition: libsheepy.c:47975
char * iUpperUTF8(char **string) MUST_CHECK
upper case UTF-8 encoded string
Definition: libsheepy.c:48003
int commandfF(int line, const char *thisFunc, const char *thisFileName, const char *fmt,...) MUST_CHECK
run command with formatting in default shell
Definition: libsheepy.c:54551
int commandF(const char *cmd, int line, const char *thisFunc, const char *thisFileName) MUST_CHECK
run command in default shell
Definition: libsheepy.c:54514
char * toHexSepS(const void *buf, size_t len, const char *separator) MUST_CHECK
create a string with bytes in buf converted to hex strings separated by separator ...
Definition: libsheepy.c:6686
void listFreeManySF(char **paramType,...)
list free many String
Definition: libsheepy.c:50797
const char * prevUTF8(const char *utf8) MUST_CHECK
previous UTF-8 code point
Definition: libsheepy.c:46132
bool isLink(const char *path) MUST_CHECK
is symbolic link
Definition: libsheepy.c:4293
char c
char * replaceCharCharS(const char *s, char olds, char news, size_t max) MUST_CHECK
Definition: libsheepy.c:7817
fiberLT startL
fibers to start
Definition: libsheepy.h:6850
char * iicReplaceS(char **s, const char *olds, const char *news, size_t max) MUST_CHECK
in place ignore case replace String the olds string is replaced with the news string max times in the...
Definition: libsheepy.c:8537
void(* initLibsheepyObjectP)(void)
Definition: libsheepy.h:1597
char ** iListCopyS(char **list, int64_t start, int64_t end) MUST_CHECK
list Copy String return new list with element pointers from start and end in list negative indexes ar...
Definition: libsheepy.c:52552
char * catSF(const char *paramType,...) MUST_CHECK
cat String Function
Definition: libsheepy.c:6998
char * bLJoin(char *string, size_t stringSize, char **list, const char *delim) MUST_CHECK
buffer size join list, the elements are seperated with delim in the resulting string ...
Definition: libsheepy.c:51720
char * doubleToS(double n) MUST_CHECK
double To String
Definition: libsheepy.c:11008
ssize_t readFile(const char *filePath, void **buffer) MUST_CHECK
read file to buffer
Definition: libsheepy.c:4726
char * lTrimS(const char *string) MUST_CHECK
left trim String duplicate string
Definition: libsheepy.c:11397
size_t lenS(const char *string) MUST_CHECK
length string
Definition: libsheepy.c:11047
fibersT fibers
data for fiber system
Definition: libsheepy.c:57307
char ** iListInjectS(char ***list, int64_t index, char *toInject) MUST_CHECK
list Inject string
Definition: libsheepy.c:53339
char * iicReplaceCharSS(char **s, char olds, const char *news, size_t max) MUST_CHECK
Definition: libsheepy.c:8616
void cleanUpFd(int *val)
Definition: libsheepy.c:939
char * iRTrimS(char **string) MUST_CHECK
right trim String
Definition: libsheepy.c:11529
ssize_t listIndexOfCS(const char **list, const char *string) MUST_CHECK
return index of string in const list
Definition: libsheepy.c:54813
bool getLogShortPath(void) MUST_CHECK
get current log long/short path value
Definition: libsheepy.c:1128
char * iReplaceManySF(char **string, char *paramType,...) MUST_CHECK
replace Many Strings the olds string is replaced with the news string max times in the result ...
Definition: libsheepy.c:8263
int64_t bLPtr2NegIdxUTF8(const char *utf8, size_t utf8Size, const char *pos) MUST_CHECK
buffer size pointer to negative code point index UTF8 encoded string
Definition: libsheepy.c:46556
char ** iListAppendNSmashS(char ***list1, char **list2) MUST_CHECK
list Append and smash list2 Append list2 at the end of list1 by copying the pointers from list2 to li...
Definition: libsheepy.c:52273
char ** systemOutf(const char *fmt,...) MUST_CHECK
execute system command with formatting
Definition: libsheepy.c:54458
ssize_t indexOfUTF8(const char *string, const char *needle) MUST_CHECK
indexOf UTF8 encoded String relative to start
Definition: libsheepy.c:49726
int ringIsFull(void *ring)
1 when full 0 not full -1 error
Definition: libsheepy.c:57137
char * replaceCharSS(const char *s, char olds, const char *news, size_t max) MUST_CHECK
Definition: libsheepy.c:7805
ssize_t listIndexOfS(char **list, const char *string) MUST_CHECK
return index of string in list
Definition: libsheepy.c:54779
int systemf(const char *fmt,...) MUST_CHECK
execute system command with formatting
Definition: libsheepy.c:54484
size_t listLength(void **list) MUST_CHECK
list Length return number of elements until the first NULL element
Definition: libsheepy.c:55994
char ** iListEmptySF(char ***list) MUST_CHECK
list Empty String Function
Definition: libsheepy.c:50322
char * escapeS(const char *s, char delim) MUST_CHECK
escape string according the json specification (RFC 8259) if there is in the string, the backslash is escaped and it will be parsed as the string &#39;&#39; be the json parsers the unicode characters should be converted to UTF8 codepoints instead of using the result can be included in a json string and the parsing will be correct
Definition: libsheepy.c:10045
int ringEmpty(void *ring)
empty ring Allocated buffers in the list must be freed before running staticArrayEmpty ...
Definition: libsheepy.c:57104
void * memdup(const void *buf, size_t size) MUST_CHECK
memory duplicate allocate and copy buffer
Definition: libsheepy.c:6448
char * iUniqS(char **string, char c) MUST_CHECK
uniq String
Definition: libsheepy.c:11638
bool isBlankS(const char *string) MUST_CHECK
is Blank String
Definition: libsheepy.c:50246
void ** listPrepend(void ***list, void *s) MUST_CHECK
list Prepend
Definition: libsheepy.c:55874
char * bLQuoteS(char *dest, size_t destSize, const char *s, char delim) MUST_CHECK
add backslash &#39;\&#39; before delim(&#39;\&#39;&#39; or &#39;"&#39;) and backslash the backslashes in the result avoid splitti...
Definition: libsheepy.c:9959
ssize_t ellipsisLenS(const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK
length of string after ellipsis
Definition: libsheepy.c:12511
char ** listSortS(char **list) MUST_CHECK
list Sort String duplicate list and sort
Definition: libsheepy.c:53898
int64_t getStackLimit(void) MUST_CHECK
get current stack limit
Definition: libsheepy.c:1667
smallStringt * S
int ringPop(void *ring)
pop element from ring (only decreases last)
Definition: libsheepy.c:57215
char ** listSliceS(char **list, int64_t start, int64_t end) MUST_CHECK
list Slice String return new list with elements from start and end in list negative indexes are allow...
Definition: libsheepy.c:52479
char ** iListRemoveS(char ***list, int64_t start, int64_t end)
list Remove String return list without elements from start and end in list the elements are removed w...
Definition: libsheepy.c:53595
void readEnter(void)
read Enter key wait until press the enter key
Definition: libsheepy.c:6468
char * icReplaceSCharS(const char *s, const char *olds, char news, size_t max) MUST_CHECK
Definition: libsheepy.c:8509
void setHardwareRandom(void)
use cpu hardware random number generator
Definition: libsheepy.c:5878
bool listEqC1S(const char **list1, char **list2) MUST_CHECK
const(list1) list Equal String compare each element of list1 and list2
Definition: libsheepy.c:54659
char * bLSliceS(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK
buffer size slice String return string which is the string between start and end negative indexes are...
Definition: libsheepy.c:14355
char * iListCropElemS(char ***list, int64_t index) MUST_CHECK
list Crop Element String return element at index and delete element at index in the original list neg...
Definition: libsheepy.c:52933
char * shDirname(const char *path) MUST_CHECK
sheepy dirname
Definition: libsheepy.c:2191
bool zeroS(char *string) MUST_CHECK
write zero to all bytes in string with memset, for clearing password buffers
Definition: libsheepy.c:6403
int writeLStream(FILE *fp, void *buffer, size_t len) MUST_CHECK
write buffer to file
Definition: libsheepy.c:4995
char * iicReplaceSCharUTF8(char **s, const char *olds, char news, size_t max) MUST_CHECK
char * bDelElemS(char *string, int64_t index) MUST_CHECK
buffer delete element/character string
Definition: libsheepy.c:15707
bool icEqIS(const char *string1, const char *string2, int64_t index) MUST_CHECK
ignore case string Index Equal compare string1 at index to string2 when string2 is empty...
Definition: libsheepy.c:9323
int systemNFreeF(char *command, int line, const char *thisFunc, const char *thisFileName) MUST_CHECK
run system command and free command buffer a message is printed when an error occurs ...
Definition: libsheepy.c:1844
char * bPadEndCharS(char *dest, const char *string, size_t targetLength, char padChar) MUST_CHECK
pad end string
Definition: libsheepy.c:13745
void listFreeManyF(void **paramType,...)
list free many
Definition: libsheepy.c:55971
char * iSliceUTF8(char **string, int64_t start, int64_t end) MUST_CHECK
slice UTF8 encoded String return string which is the string between start and end negative indexes ar...
Definition: libsheepy.c:48712
char * bCEscapeS(char *dest, const char *S) MUST_CHECK
escape string to become a valid C source string control characters, backslash and double quotes are e...
Definition: libsheepy.c:10459
char * strNCpyUTF8(char *dst, const char *src, size_t srcLen) MUST_CHECK
strNCpyUTF8 - copy src to dst with srcLen in code points
Definition: libsheepy.c:46875
char * iEmptySF(char **string) MUST_CHECK
empty String Function
Definition: libsheepy.c:50202
char ** iListAppendS(char ***list1, char **list2) MUST_CHECK
in place list Append String Append list2 at the end of list1 by copying the pointers from list2 to li...
Definition: libsheepy.c:52199
char * bUpperS(char *string) MUST_CHECK
buffer upper case String
Definition: libsheepy.c:11139
char * bLRelPath(char *dest, size_t destSize, char *path, const char *start) MUST_CHECK
relative path
Definition: libsheepy.c:3860
char * toHexS(const void *buf, size_t len) MUST_CHECK
create a string with bytes in buf converted to hex strings
Definition: libsheepy.c:6648
double parseDouble(const char *string) MUST_CHECK
convert string to double
Definition: libsheepy.c:10914
char * readS(void) MUST_CHECK
read String read user input (one line) as a string
Definition: libsheepy.c:6244
time_t getModificationTime(const char *path) MUST_CHECK
get modification time for path
Definition: libsheepy.c:1864
char iCropElemS(char **string, int64_t index) MUST_CHECK
Definition: libsheepy.c:14583
char * iUniqUTF8(char **string, const char *code) MUST_CHECK
uniq UTF-8 String
Definition: libsheepy.c:48409
time_t getCurrentUnixTime(void) MUST_CHECK
get current unix time in seconds
Definition: libsheepy.c:2001
char * bLEllipsisStartCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK
ellipsis start string
Definition: libsheepy.c:12463
int64_t bLPtr2IdxUTF8(const char *utf8, size_t utf8Size, const char *pos) MUST_CHECK
buffer size pointer to code point index UTF8 encoded string
Definition: libsheepy.c:46505
char * iAppendManySF(char **string, const char *paramType,...) MUST_CHECK
append many strings
Definition: libsheepy.c:7388
int listPrintS(char **list) MUST_CHECK
print list elements to stdout
Definition: libsheepy.c:53841
char * bLowerUTF8(char *string) MUST_CHECK
bool icEndsWithUTF8(const char *string1, const char *string2) MUST_CHECK
ignore case ends With UTF8 encoded String compare end of string1 with string2
Definition: libsheepy.c:47444
char ** icListSortS(char **list) MUST_CHECK
ignore case list Sort String duplicate list and sort
Definition: libsheepy.c:54039
bool listHasS(char **list, const char *string) MUST_CHECK
return true when list has string
Definition: libsheepy.c:54721
char ** icListUniqS(char **list) MUST_CHECK
ignore case and uniquify elements of list duplicate list each elements are unique in the new list ...
Definition: libsheepy.c:55289
char * bDelS(char *string, int64_t start, int64_t end) MUST_CHECK
buffer delete string
Definition: libsheepy.c:15487
char * bDelUTF8(char *string, int64_t start, int64_t end) MUST_CHECK
buffer delete UTF8 encoded string
Definition: libsheepy.c:49576
char * lowerUTF8(const char *string) MUST_CHECK
lower case UTF-8 String duplicate string
Definition: libsheepy.c:48228
void ** listReverse(void **list) MUST_CHECK
list Reverse create index list and reverse list, the last element is the first element of the new lis...
Definition: libsheepy.c:56145
char ** listDelS(char **list, int64_t start, int64_t end) MUST_CHECK
list Delete String return new list without elements from start and end in list negative indexes are a...
Definition: libsheepy.c:53435
ssize_t icListBinarySearchS(char **list, const char *string) MUST_CHECK
ignore case list binary search string
Definition: libsheepy.c:55248
char ** listFromArrayS(char **array, size_t size) MUST_CHECK
list From Array String
Definition: libsheepy.c:50427
char * bLDelUTF8(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK
buffer size delete UTF8 encoded string
Definition: libsheepy.c:49647
void * listDequeue(void ***list) MUST_CHECK
list Dequeue return first element from list and remove last element from the list ...
Definition: libsheepy.c:55920
char ** readDir(const char *dirPath) MUST_CHECK
list files in a directory and sort the list
Definition: libsheepy.c:5227
void ** listInsert(void **list, int64_t index, void **toInsert) MUST_CHECK
list Insert
Definition: libsheepy.c:56522
int setModificationTime(const char *path, time_t mtime) MUST_CHECK
set modification time for path
Definition: libsheepy.c:1890
bool listEqS(char **list1, char **list2) MUST_CHECK
list Equal String compare each element of list1 and list2
Definition: libsheepy.c:54599
int writeStreamS(FILE *fp, const char *string) MUST_CHECK
write string to file
Definition: libsheepy.c:4963
char * bExpandHome(char *path) MUST_CHECK
buffer expands ~/ ($HOME) or ~USER
Definition: libsheepy.c:2821
char ** iListInjectCharS(char ***list, int64_t index, char toInject) MUST_CHECK
Definition: libsheepy.c:53403
char * bLicReplaceManyUTF8F(char *s, size_t sSize, char *paramType,...) MUST_CHECK
char ** listAddS(char **list1, char **list2)
list Add String add list1 and list2 in a new list
Definition: libsheepy.c:52372
char ** iListSortFS(char ***list, shCmpt compareFunction) MUST_CHECK
list Sort String
Definition: libsheepy.c:53987
char * bDoubleToS(char *s, double n) MUST_CHECK
buffer double To String
Definition: libsheepy.c:11027
char * icTokS(char *s, const char *delim, char **saveptr) MUST_CHECK
ignore case token in String
Definition: libsheepy.c:16038
int getLogMode(void) MUST_CHECK
get current log mode (verbose, concise)
Definition: libsheepy.c:1097
char * bFormatS(char *string, const char *fmt,...) MUST_CHECK
format and store in string: bFormatS(string, "Value %d", i);
Definition: libsheepy.c:7117
char * insertNFreeUTF8(const char *string, int64_t index, char *toInsert) MUST_CHECK
insert string in UTF8 encoded string at index and free toInsert
Definition: libsheepy.c:49029
const char * nextUTF8(const char *utf8) MUST_CHECK
next UTF-8 code point
Definition: libsheepy.c:46037
ssize_t icCountS(const char *s, const char *needle) MUST_CHECK
ignore case count String count number of (non-overlapping) occurrences of a substring ...
Definition: libsheepy.c:9446
char ** listInsertS(char **list, int64_t index, char **toInsert) MUST_CHECK
list Insert string
Definition: libsheepy.c:52986
uint64_t shStopwatch(uint8_t op)
nanosecond stopwatch
Definition: libsheepy.c:955
char * bRepeatCharS(char *dest, char c, size_t count) MUST_CHECK
repeat char count times
Definition: libsheepy.c:12055
bool icListEqUTF8(char **list1, char **list2) MUST_CHECK
ignore case list Equal UTF8 encoded String compare each element of list1 and list2 ...
Definition: libsheepy.c:49961
void shPrintfS(const char *fmt,...)
sheepy Print String
Definition: libsheepy.c:6566
char ** listCatSF(char **paramType,...) MUST_CHECK
list Cat String
Definition: libsheepy.c:52086
char * icReplaceManyUTF8F(const char *paramType,...) MUST_CHECK
char * iInsertNFreeUTF8(char **string, int64_t index, char *toInsert) MUST_CHECK
insert string in UTF8 encoded string at index and free toInsert
Definition: libsheepy.c:49191
char * bEllipsisEndCharS(char *dest, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK
ellipsis end string
Definition: libsheepy.c:12847
char * iInsertNFreeS(char **string, int64_t index, char *toInsert) MUST_CHECK
insert string in string at index and free toInsert
Definition: libsheepy.c:14835
bool fileChmod(const char *filePath, mode_t mode) MUST_CHECK
like chmod in stdlibc but return true/false
Definition: libsheepy.c:4345
char ** icExtractSCharS(const char *string, const char *delim1, char delim2) MUST_CHECK
Definition: libsheepy.c:51884
char * iReplaceSCharS(char **s, const char *olds, char news, size_t max) MUST_CHECK
Definition: libsheepy.c:7977
char * bRTrimS(char *string) MUST_CHECK
buffer right trim String
Definition: libsheepy.c:11559
bool icStartsWithCharS(const char *string1, char c) MUST_CHECK
Definition: libsheepy.c:9383
void ** listCreateF(void *paramType,...) MUST_CHECK
list Create Function create a list from the list of parameters used from the listCreate(...) macro
Definition: libsheepy.c:55716
bool icListHasCharS(char **list, char c) MUST_CHECK
Definition: libsheepy.c:55119
char ** icSplit(const char *string, const char *delim) MUST_CHECK
ignore case split string with delim string when updating this function, also update icSplitS (identic...
Definition: libsheepy.c:51407
char ** listInjectCharS(char **list, int64_t index, char toInject) MUST_CHECK
Definition: libsheepy.c:53313
char * bJoinChar(char *string, char **list, char delim) MUST_CHECK
Definition: libsheepy.c:51703
char * bNMakeValidUTF8(char *dst, const char *utf8, size_t utf8Len) MUST_CHECK
buffer length make valid UTF-8 encoded string
Definition: libsheepy.c:46724
smallArrayt * a
char * iRelPath(char **path, const char *start) MUST_CHECK
relative path
Definition: libsheepy.c:3599
char * swapS(char *string, int64_t index1, int64_t index2) MUST_CHECK
swap characters in string
Definition: libsheepy.c:13933
char * icReplaceS(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK
ignore case Replace String the original remains unchanged duplicate s the olds string is replaced wit...
Definition: libsheepy.c:8429
ssize_t icListBinarySearchUTF8(char **list, const char *string) MUST_CHECK
ignore case list binary search UTF8 encoded string
Definition: libsheepy.c:50055
char * bLFormatS(char *string, size_t stringSize, const char *fmt,...) MUST_CHECK
format and store in string: bLFormatS(string, sizeof(string), "Value %d", i);
Definition: libsheepy.c:7140
int writeFile(const char *filePath, void *buffer, size_t len) MUST_CHECK
write buffer to file
Definition: libsheepy.c:4925
char * appendS(const char *string1, const char *string2) MUST_CHECK
append strings
Definition: libsheepy.c:7166
char * bLicReplaceManySF(char *s, size_t sSize, char *paramType,...) MUST_CHECK
buffer size ignore case replace Many Strings the olds string is replaced with the news string max tim...
Definition: libsheepy.c:9016
char * intToS(int64_t n) MUST_CHECK
int To String
Definition: libsheepy.c:10970
char * bLInsertUTF8(char *string, size_t stringSize, int64_t index, const char *toInsert) MUST_CHECK
buffer size insert string in UTF8 encoded string at index
Definition: libsheepy.c:49347
bool startsWithS(const char *string1, const char *string2) MUST_CHECK
starts With String compare start of string1 with string2
Definition: libsheepy.c:9158
char * iInjectS(char **string, int64_t index, char toInject) MUST_CHECK
inject a char in string at index
Definition: libsheepy.c:15131
void ** listFromArray(void **array, size_t size) MUST_CHECK
list From Array
Definition: libsheepy.c:55748
char * toHexHeadSepS(const void *buf, size_t len, const char *head, const char *separator) MUST_CHECK
create a string with bytes in buf converted to hex strings separated by separator and with head strin...
Definition: libsheepy.c:6728
int64_t bPtr2IdxUTF8(const char *start, const char *utf8, const char *pos) MUST_CHECK
buffer pointer to code point index UTF8 encoded string
Definition: libsheepy.c:46444
char * strLCpyUTF8(char *dst, size_t dstSize, const char *src) MUST_CHECK
strLCpyUTF8 - copy src to dst
Definition: libsheepy.c:46912
char * bInjectS(char *string, int64_t index, char toInject) MUST_CHECK
buffer inject a char in string at index
Definition: libsheepy.c:15208
char * iLTrimS(char **string) MUST_CHECK
left trim String
Definition: libsheepy.c:11430
char * icTokUTF8(const char *s, const char *delim, char **saveptr) MUST_CHECK
char * bLJoinChar(char *string, size_t stringSize, char **list, char delim) MUST_CHECK
Definition: libsheepy.c:51745
const char * bLIdx2PtrUTF8(const char *utf8, size_t utf8Size, int64_t index) MUST_CHECK
Definition: libsheepy.c:46306
char ** iListUniqS(char ***list) MUST_CHECK
Uniquify elements of list each elements are unique in the list.
Definition: libsheepy.c:54942
char * bStripColorsS(char *string) MUST_CHECK
remove terminal control char from string
Definition: libsheepy.c:9768
ssize_t repeatLenS(const char *string, size_t count) MUST_CHECK
length of string repeated count times
Definition: libsheepy.c:12093
char * icReplaceSCharUTF8(const char *s, const char *olds, char news, size_t max) MUST_CHECK
rune code2RuneLUTF8(const char *code, uint8_t *n) MUST_CHECK
UTF-8 code point to rune and length.
Definition: libsheepy.c:47569
char * bLEllipsisEndCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK
ellipsis end string
Definition: libsheepy.c:12898
bool isExecutable(const char *path) MUST_CHECK
is path executable
Definition: libsheepy.c:1954
int setStackLimit(int64_t stackSize) MUST_CHECK
set stack limit
Definition: libsheepy.c:1686
char * iPrependS(char **string1, const char *string2) MUST_CHECK
prepend strings
Definition: libsheepy.c:7557
char * iicReplaceCharCharS(char **s, char olds, char news, size_t max) MUST_CHECK
Definition: libsheepy.c:8628
char * iLowerUTF8(char **string) MUST_CHECK
lower case String
Definition: libsheepy.c:48256
char * iPadEndS(char **string, size_t targetLength, const char *padString) MUST_CHECK
pad end string
Definition: libsheepy.c:13473
char ** icExtractCharSS(const char *string, char delim1, const char *delim2) MUST_CHECK
Definition: libsheepy.c:51878
void ** listDel(void **list, int64_t start, int64_t end) MUST_CHECK
list Delete return new list without elements from start and end in list negative indexes are allowed ...
Definition: libsheepy.c:56684
ssize_t icListBinarySearchCharS(char **list, char c) MUST_CHECK
Definition: libsheepy.c:55271
char * bicReplaceManyUTF8F(char *s, char *paramType,...) MUST_CHECK
char * repeatS(const char *string, size_t count) MUST_CHECK
repeat string count times
Definition: libsheepy.c:11865
ssize_t fileSize(const char *filePath) MUST_CHECK
get file size
Definition: libsheepy.c:4369
char * iicReplaceUTF8(char **s, const char *olds, const char *news, size_t max) MUST_CHECK
bool icEndsWithS(const char *string1, const char *string2) MUST_CHECK
ignore case ends With String compare end of string1 with string2
Definition: libsheepy.c:9401
char * iPrependNFreeS(char **string1, char *string2) MUST_CHECK
prepend and free strings
Definition: libsheepy.c:7634
bool icEqICharS(const char *string1, char c, int64_t index) MUST_CHECK
Definition: libsheepy.c:9358
char ** listShiftS(char ***list1, char **list2) MUST_CHECK
list Shift String Append list2 at the start of list1
Definition: libsheepy.c:52298
char * bRelPath(char *dest, const char *path, const char *start) MUST_CHECK
relative path
Definition: libsheepy.c:3730
char * stripCtrlS(const char *string) MUST_CHECK
remove terminal control char from string
Definition: libsheepy.c:9521
char * iCropS(char **string, int64_t start, int64_t end) MUST_CHECK
Crop String return a new string with characters from start and end in string and delete characters fr...
Definition: libsheepy.c:14501
const char * getCHomePath(void) MUST_CHECK
get home path as a const char*
Definition: libsheepy.c:4039
char getS(const char *string, int64_t index) MUST_CHECK
get string
Definition: libsheepy.c:13872
char * icFindCharS(const char *string, char c) MUST_CHECK
Definition: libsheepy.c:15897
ssize_t icCountUTF8(const char *s, const char *needle) MUST_CHECK
ignore case count UTF8 encoded String count number of (non-overlapping) occurrences of a substring ...
Definition: libsheepy.c:47480
int64_t parseI64(const char *string) MUST_CHECK
convert string to decimal integer
Definition: libsheepy.c:10880
char ** listSortFS(char **list, shCmpt compareFunction) MUST_CHECK
list Sort String duplicate list and sort
Definition: libsheepy.c:53956
int commandNFreeF(char *cmd, int line, const char *thisFunc, const char *thisFileName) MUST_CHECK
run command in default shell and free the cmd parameter
Definition: libsheepy.c:54581
bool zeroBuf(void *buf, size_t len) MUST_CHECK
write zero to all bytes in buffer with memset
Definition: libsheepy.c:6425
char * iEllipsisStartS(char **string, size_t targetLength, const char *ellipsisString) MUST_CHECK
ellipsis start string
Definition: libsheepy.c:12172
char * bicReplaceManySF(char *s, char *paramType,...) MUST_CHECK
buffer ignore case replace Many Strings the olds string is replaced with the news string max times in...
Definition: libsheepy.c:8962
char * iPadStartCharS(char **string, size_t targetLength, char padChar) MUST_CHECK
pad start string
Definition: libsheepy.c:13231
ssize_t ringCount(void *ring)
return elements count
Definition: libsheepy.c:57159
void listFreeS(char **list)
list Free String
Definition: libsheepy.c:50780
char * bLReplaceManySF(char *s, size_t sSize, char *paramType,...) MUST_CHECK
buffer size replace Many Strings the olds string is replaced with the news string max times in the re...
Definition: libsheepy.c:8371
uint64_t getMonotonicTime(void) MUST_CHECK
end bitfield
Definition: libsheepy.c:57411
size_t lenUTF8(const char *s) MUST_CHECK
character length of UTF-8 string
Definition: libsheepy.c:16076
char * bMakeValidUTF8(char *utf8) MUST_CHECK
buffer make valid UTF-8 encoded string
Definition: libsheepy.c:46635
mode_t getCurrentPermissions(void) MUST_CHECK
get current permissions for creating directories
Definition: libsheepy.c:5443
int64_t parseInt(const char *string) MUST_CHECK
convert string to decimal integer
Definition: libsheepy.c:10846
char * getCurrentDate(void) MUST_CHECK
get current date in ctime format (Wed Dec 12 11:44:08 2018)
Definition: libsheepy.c:2112
ssize_t icIndexOfS(const char *string, const char *needle) MUST_CHECK
ignore case indexOf String relative to start
Definition: libsheepy.c:15925
#define SH_PREFIX(NAME)
Definition: libsheepy.h:104
char ** listSetS(char **list, int64_t index, const char *s) MUST_CHECK
list Set String duplicate string and store at given index, the existing element is freed index can be...
Definition: libsheepy.c:51110
bool isCodeUTF8(const char *code) MUST_CHECK
is code point UTF8 encoded string
Definition: libsheepy.c:16247
bool listIsEmpty(void **list) MUST_CHECK
list Is Empty
Definition: libsheepy.c:55696
bool icEqICharUTF8(const char *string1, char c, int64_t index) MUST_CHECK
FILE *SH_PREFIX() setLogFile(char *filename)
set log file the logs are appended to all log files set with this function
Definition: libsheepy.c:1058
void * listGet(void **list, int64_t index) MUST_CHECK
list Get
Definition: libsheepy.c:56022
bool writeText(const char *filePath, char **list) MUST_CHECK
write list to filePath
Definition: libsheepy.c:54230
char * bLPadStartS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *padString) MUST_CHECK
pad start string
Definition: libsheepy.c:13123
char * bInsertUTF8(char *string, int64_t index, const char *toInsert) MUST_CHECK
buffer insert string in UTF8 encoded string at index
Definition: libsheepy.c:49275
char ** iicListSortUTF8(char ***list) MUST_CHECK
ignore case list Sort UTF8 encoded String
Definition: libsheepy.c:49934
bool icEqS(const char *string1, const char *string2) MUST_CHECK
ignore case string Equal compare string1 to string2
Definition: libsheepy.c:9283
char * bLTimeToYMDS(char *dst, size_t dstSize, const time_t t) MUST_CHECK
Definition: libsheepy.c:2099
bool appendFileS(const char *filePath, const char *string) MUST_CHECK
append string to filePath
Definition: libsheepy.c:5023
size_t bRune2CodeUTF8(char *dst, rune c) MUST_CHECK
rune to UTF-8 code point
Definition: libsheepy.c:47635
char * cEscapeS(const char *S) MUST_CHECK
escape string to become a valid C source string control characters, backslash and double quotes are e...
Definition: libsheepy.c:10328
char ** listPushS(char ***list, const char *s) MUST_CHECK
list Push String append s at the end of the list when list is NULL, a new list with one element is re...
Definition: libsheepy.c:50504
char * bPrependS(char *string1, const char *string2) MUST_CHECK
buffer prepend strings
Definition: libsheepy.c:7655
uint64_t randomWord(void) MUST_CHECK
return random 64 bit unsigned integer call randomUrandomOpen before this calling function ...
Definition: libsheepy.c:5933
char ** iListPushS(char ***list, char *s) MUST_CHECK
list Push String append s pointer at the end of the list when list is NULL, a new list with one eleme...
Definition: libsheepy.c:50559
double parseDoubleChar(char c) MUST_CHECK
Definition: libsheepy.c:10927
char * strLNCat(char *restrict dst, size_t dstSize, const char *restrict src, size_t srcLen) MUST_CHECK
strLNCat - concatenate two strings
Definition: libsheepy.c:6966
char * lowerS(const char *string) MUST_CHECK
lower case String duplicate string
Definition: libsheepy.c:11164
i64 ringPush(void *ring)
push element to ring (only increases last, use ringSend) use ringLast to access the element ...
Definition: libsheepy.c:57186
char * iReplaceCharCharS(char **s, char olds, char news, size_t max) MUST_CHECK
Definition: libsheepy.c:7983
bool icEqIUTF8(const char *string1, const char *string2, int64_t index) MUST_CHECK
void freeRealProgPath(void)
free real program path finalizeLibsheepy calls this function
Definition: libsheepy.c:1826
ssize_t icListIndexOfCharCS(const char **list, char c) MUST_CHECK
Definition: libsheepy.c:55228
char * bLGetHomePath(char *path, size_t pathSize) MUST_CHECK
copy home path to path maximum pathSize
Definition: libsheepy.c:4020
bool r
void setLogShortPath(bool shortPath)
set log long/short file path value for VERBOSE mode
Definition: libsheepy.c:1141
char * prependS(const char *string1, const char *string2) MUST_CHECK
prepend strings
Definition: libsheepy.c:7511
char ** readStream(FILE *fp) MUST_CHECK
return text from stream fp in a list new line characters are removed
Definition: libsheepy.c:54187
bool startsWithCharS(const char *string1, char c) MUST_CHECK
Definition: libsheepy.c:9167
char * bDirname(char *path) MUST_CHECK
buffer dirname
Definition: libsheepy.c:2252
int shMove(const char *src, const char *dst) MUST_CHECK
move files recursively
Definition: libsheepy.c:5845
char * uniqS(const char *string, char c) MUST_CHECK
uniq String duplicate string
Definition: libsheepy.c:11592
char ** icListUniqUTF8(char **list) MUST_CHECK
ignore case and uniquify UTF8 encoded elements of list duplicate list each elements are unique in the...
Definition: libsheepy.c:50098
size_t listLengthCS(const char **list) MUST_CHECK
const list Length String return number of elements until the first NULL element
Definition: libsheepy.c:50843
const char * iListGetCS(const char **list, int64_t index) MUST_CHECK
const list Get String index can be negative
Definition: libsheepy.c:51070
char * strNCatUTF8(char *dst, const char *src, size_t srcLen) MUST_CHECK
strNCatUTF8 - concatenate two UTF-8 encoded strings
Definition: libsheepy.c:46941
char * padEndCharS(const char *string, size_t targetLength, char padChar) MUST_CHECK
pad end string
Definition: libsheepy.c:13649
rune getUTF8(const char *string, int64_t index) MUST_CHECK
get UTF8 encoded string
Definition: libsheepy.c:48567
char * bLExpandHome(char *path, size_t pathSize) MUST_CHECK
buffer size expands ~/ ($HOME) or ~USER
Definition: libsheepy.c:3001
char * bLTrimS(char *string) MUST_CHECK
buffer left trim String
Definition: libsheepy.c:11464
char ** listAddCS(char **list1, const char **list2)
const list Add String add list1 and list2 in a new list
Definition: libsheepy.c:52423
bool listHasCharCS(const char **list, char c) MUST_CHECK
Definition: libsheepy.c:54761
char * iicReplaceSCharS(char **s, const char *olds, char news, size_t max) MUST_CHECK
Definition: libsheepy.c:8622
#define tCount
Definition: libsheepy.h:6820
ssize_t indexOfCharS(const char *string, char c) MUST_CHECK
Definition: libsheepy.c:15830
char ** listInjectS(char **list, int64_t index, char *toInject) MUST_CHECK
list Inject string
Definition: libsheepy.c:53254
char * insertS(const char *string, int64_t index, const char *toInsert) MUST_CHECK
insert string in string at index
Definition: libsheepy.c:14609
bool btraceConfig(void) MUST_CHECK
Definition: libsheepy.c:55451
char * icUniqUTF8(const char *string, const char *code) MUST_CHECK
char * bPadStartCharS(char *dest, const char *string, size_t targetLength, char padChar) MUST_CHECK
pad start string
Definition: libsheepy.c:13277
ssize_t icListIndexOfUTF8(char **list, const char *string) MUST_CHECK
ignore case and return index of UTF8 encoded string in list
Definition: libsheepy.c:50018
char ** iicListUniqS(char ***list) MUST_CHECK
ignore case and uniquify elements of list each elements are unique in the list
Definition: libsheepy.c:55329
size_t replaceSLen(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK
replaceSLen returns the length of the resulting string
Definition: libsheepy.c:7827
char * bLGetCurrentDateYMD(char *dst, size_t dstSize) MUST_CHECK
Definition: libsheepy.c:2168
char * strLNCatUTF8(char *dst, size_t dstSize, const char *src, size_t srcLen) MUST_CHECK
strLNCatUTF8 - concatenate two UTF-8 encoded strings
Definition: libsheepy.c:47023
char * bIntToS(char *s, int64_t n) MUST_CHECK
buffer int To String
Definition: libsheepy.c:10989
char ** listAddrS(char **list, int64_t index) MUST_CHECK
list address String index can be negative
Definition: libsheepy.c:50929
bool listEqCS(char **list1, const char **list2) MUST_CHECK
const(list2) list Equal String compare each element of list1 and list2
Definition: libsheepy.c:54629
#define command(cmd)
Definition: libsheepy.h:3151
char * padEndS(const char *string, size_t targetLength, const char *padString) MUST_CHECK
pad end string
Definition: libsheepy.c:13417
int chDir(const char *path) MUST_CHECK
change directory
Definition: libsheepy.c:4092
const char * getProgName(void) MUST_CHECK
get program name
Definition: libsheepy.c:1745
char * icReplaceCharCharS(const char *s, char olds, char news, size_t max) MUST_CHECK
Definition: libsheepy.c:8515
char * bLCatSF(char *dst, size_t dstSize, const char *paramType,...) MUST_CHECK
cat and copy String Function
Definition: libsheepy.c:7057
bool listIsEmptyS(char **list) MUST_CHECK
list Is Empty String
Definition: libsheepy.c:50351
char ** listCompactS(char **list) MUST_CHECK
remove empty strings from list
Definition: libsheepy.c:55373
int copy(const char *src, const char *dst) MUST_CHECK
copy files recursively This function is equivalent to &#39;cp -Ra&#39; without wildcards and circular link de...
Definition: libsheepy.c:5590
bool btraceCfg
backtrace in error messages is enabled by default
Definition: libsheepy.c:867
char ** iicListUniqUTF8(char ***list) MUST_CHECK
ignore case and uniquify UTF8 encoded elements of list each elements are unique in the list ...
Definition: libsheepy.c:50139
void shEPrintfS(const char *fmt,...)
sheepy Error printf String print with logE
Definition: libsheepy.c:6589
int mkdirParents(const char *path) MUST_CHECK
recursive mkdir
Definition: libsheepy.c:5457
char ** readDirDir(const char *dirPath) MUST_CHECK
list directories in a directory and sort the list
Definition: libsheepy.c:5279
char * joinCS(const char **list, const char *delim) MUST_CHECK
join list, the elements are seperated with delim in the resulting string
Definition: libsheepy.c:51633
const char * idx2PtrUTF8(const char *utf8, int64_t index) MUST_CHECK
index to pointer UTF8 encoded string
Definition: libsheepy.c:46207
int ringDequeue(void *ring)
dequeue element from ring (only increases head, use ringRecv)
Definition: libsheepy.c:57282
char ** iListShiftNSmashS(char ***list1, char **list2) MUST_CHECK
list Append and smash list2 Append list2 at the start of list1 by copying the pointers from list2 to ...
Definition: libsheepy.c:52354
char * bLNMakeValidUTF8(char *dst, size_t dstSize, const char *utf8, size_t utf8Len) MUST_CHECK
buffer destination size source length make valid UTF-8 encoded string
Definition: libsheepy.c:46825
ssize_t intIndex(int64_t index, int64_t length)
int to positive index index can be negative
Definition: libsheepy.c:50275
char * getCurrentDateYMD(void) MUST_CHECK
get current date in Y-m-d H:M:S format
Definition: libsheepy.c:2148
bool hasCharS(const char *string, char c) MUST_CHECK
Definition: libsheepy.c:15864
bool appendFile(const char *filePath, void *buffer, size_t len) MUST_CHECK
append buffer to file
Definition: libsheepy.c:5064
char * bLPadEndS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *padString) MUST_CHECK
pad end string
Definition: libsheepy.c:13589
char * nMakeValidUTF8(const char *utf8, size_t utf8Len) MUST_CHECK
length make valid UTF-8 encoded string
Definition: libsheepy.c:46672
char * iPadEndCharS(char **string, size_t targetLength, char padChar) MUST_CHECK
pad end string
Definition: libsheepy.c:13697
char ** iicListSortS(char ***list) MUST_CHECK
ignore case list Sort String
Definition: libsheepy.c:54069
char * bLNormalizePath(char *path, size_t pathSize) MUST_CHECK
buffer size normalize path
Definition: libsheepy.c:3367
bool eqIUTF8(const char *string1, const char *string2, int64_t index) MUST_CHECK
UTF8 encoded string Index Equal compare string1 at character index to string2 when string2 is empty...
Definition: libsheepy.c:47312
bool listHasCS(const char **list, const char *string) MUST_CHECK
return true when const list has string
Definition: libsheepy.c:54744
char * bLPrependS(char *string1, size_t string1Size, const char *string2) MUST_CHECK
buffer prepend strings
Definition: libsheepy.c:7687
char * ellipsisEndS(const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK
ellipsis end string
Definition: libsheepy.c:12546
void randomUrandomClose(void)
close /dev/urandom in libsheepy call this function when random are not needed anymore ...
Definition: libsheepy.c:5916
char * iLowerS(char **string) MUST_CHECK
lower case String
Definition: libsheepy.c:11195
bool icListEqCS(char **list1, const char **list2) MUST_CHECK
ignore case const(list2) list Equal String compare each element of list1 and list2 ...
Definition: libsheepy.c:55016
char * bLPadEndCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char padChar) MUST_CHECK
pad end string
Definition: libsheepy.c:13800
ssize_t icCountCharS(const char *s, char c) MUST_CHECK
Definition: libsheepy.c:9470
void * readStreamToS(FILE *fp) MUST_CHECK
read file to string
Definition: libsheepy.c:4482
data type for fiber system
Definition: libsheepy.h:6838
bool isDir(const char *path) MUST_CHECK
is directory
Definition: libsheepy.c:4119
bool isUTF8(const char *string) MUST_CHECK
is UTF-8 string
Definition: libsheepy.c:16124
char ** iListSwapS(char **list, int64_t index1, int64_t index2) MUST_CHECK
swap elements in list
Definition: libsheepy.c:51245
bool icListHasCS(const char **list, const char *string) MUST_CHECK
ignore case and return true when const list has string
Definition: libsheepy.c:55137
char * bicReplaceS(char *s, const char *olds, const char *news, size_t max) MUST_CHECK
buffer ignore case replace String the olds string is replaced with the news string max times in the r...
Definition: libsheepy.c:8649
char * bGetCurrentDateYMD(char *dst) MUST_CHECK
Definition: libsheepy.c:2157
#define u8
Definition: libsheepy.h:445
char * trimS(const char *string) MUST_CHECK
trim String duplicate string
Definition: libsheepy.c:11245
char * bNormalizePath(char *path) MUST_CHECK
buffer normalize path
Definition: libsheepy.c:3260
char * bLInjectS(char *string, size_t stringSize, int64_t index, char toInject) MUST_CHECK
buffer size inject a char in string at index
Definition: libsheepy.c:15274
ssize_t indexOfS(const char *string, const char *needle) MUST_CHECK
indexOf String relative to start
Definition: libsheepy.c:15821
int ringIsEmpty(void *ring)
1 when empty 0 not empty -1 error
Definition: libsheepy.c:57121
bool icListEqS(char **list1, char **list2) MUST_CHECK
ignore case list Equal String compare each element of list1 and list2
Definition: libsheepy.c:54986
char * readPasswordS(void) MUST_CHECK
read hidden password string
Definition: libsheepy.c:6377
void listFree(void **list)
list Free
Definition: libsheepy.c:55954
char * bRepeatS(char *dest, const char *string, size_t count) MUST_CHECK
repeat string count times
Definition: libsheepy.c:11956
char * iRepeatS(char **string, size_t count) MUST_CHECK
repeat string count times
Definition: libsheepy.c:11908
char * bLInsertS(char *string, size_t stringSize, int64_t index, const char *toInsert) MUST_CHECK
buffer size insert string in string at index
Definition: libsheepy.c:14986
void * listPop(void ***list) MUST_CHECK
list Pop return last element from list and remove last element from the list
Definition: libsheepy.c:55832
char * bLGetCwd(char *path, size_t pathSize) MUST_CHECK
Definition: libsheepy.c:4070
bool setProgName(const char *name) MUST_CHECK
set program name
Definition: libsheepy.c:1755
char * bAppendManySF(char *string, const char *paramType,...) MUST_CHECK
buffer append many strings
Definition: libsheepy.c:7427
bool hasCtrlChar(const char *string) MUST_CHECK
has control char
Definition: libsheepy.c:9497
void ** listCatF(void **paramType,...) MUST_CHECK
list Cat
Definition: libsheepy.c:56203
bool icHasUTF8(const char *string, const char *needle) MUST_CHECK
ignore case has UTF8 encoded String
Definition: libsheepy.c:49768
int listPrintCS(const char **list) MUST_CHECK
Definition: libsheepy.c:53852
char ** icExtractCharSUTF8(const char *string, char delim1, const char *delim2) MUST_CHECK
char ** extractS(const char *string, const char *delim1, const char *delim2) MUST_CHECK
extract string between delim1 and delim2 strings return list
Definition: libsheepy.c:51765
char * bSwapS(char *string, int64_t index1, int64_t index2) MUST_CHECK
swap characters in string
Definition: libsheepy.c:14034
char ** iListSortS(char ***list) MUST_CHECK
list Sort String
Definition: libsheepy.c:53928
bool icHasCharS(const char *string, char c) MUST_CHECK
Definition: libsheepy.c:15968
ssize_t bLReadFile(const char *filePath, void *buffer, size_t dstSize) MUST_CHECK
buffer size read file to buffer
Definition: libsheepy.c:4832
all contexts must start with fiberBaseT
Definition: libsheepy.h:6828
char * joinChar(char **list, char delim) MUST_CHECK
Definition: libsheepy.c:51666
char ** extractCharCharS(const char *string, char delim1, char delim2) MUST_CHECK
Definition: libsheepy.c:51817
char * iReplaceS(char **s, const char *olds, const char *news, size_t max) MUST_CHECK
replace String the olds string is replaced with the news string max times in the result 0 for max mea...
Definition: libsheepy.c:7892
bool writeCText(const char *filePath, const char **list) MUST_CHECK
write const list to filePath
Definition: libsheepy.c:54267
char * sliceS(const char *string, int64_t start, int64_t end) MUST_CHECK
slice String return new string which is the string between start and end negative indexes are allowed...
Definition: libsheepy.c:14148
bool eqSChar(const char *string1, char c) MUST_CHECK
Definition: libsheepy.c:9086
char * padStartS(const char *string, size_t targetLength, const char *padString) MUST_CHECK
pad start string
Definition: libsheepy.c:12955
void freeProgName(void)
free ProgName if set with setProgName
Definition: libsheepy.c:1782
char * getHomePath(void) MUST_CHECK
get home path
Definition: libsheepy.c:3983
char * bJoin(char *string, char **list, const char *delim) MUST_CHECK
buffer join list, the elements are seperated with delim in the resulting string
Definition: libsheepy.c:51683
bool icEndsWithCharS(const char *string1, char c) MUST_CHECK
Definition: libsheepy.c:9414
char ** listPushCharS(char ***list, char c) MUST_CHECK
Definition: libsheepy.c:50536
bool isEmptyS(const char *string) MUST_CHECK
is Empty String
Definition: libsheepy.c:50226
bool endsWithCharS(const char *string1, char c) MUST_CHECK
Definition: libsheepy.c:9198
char * join(char **list, const char *delim) MUST_CHECK
join list, the elements are seperated with delim in the resulting string when updating this function...
Definition: libsheepy.c:51554
bool openProgLogFile(void) MUST_CHECK
log to a file named progName.log Use closeLogFiles when finished logging
Definition: libsheepy.c:1169
#define maxTryThrowCount
setjmp buffers for try/throw,throwV macros
Definition: libsheepy.h:391
char * iCatSF(char *dst, const char *paramType,...) MUST_CHECK
cat and copy String Function dst has to be big enough to hold the result
Definition: libsheepy.c:7027