libsheepy

C lib for handling text files, strings and json like data structure with an object oriented system
git clone https://spartatek.se/git/libsheepy.git
Log | Files | Refs | README | LICENSE

libsheepy.h (240569B)


      1 // MIT License
      2 //
      3 // Copyright (c) 2026 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__) && !defined(__riscv)
     40 #include <immintrin.h>
     41 #endif // #if !defined(__arm__) && !defined(__aarch64__) && !defined(__riscv)
     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 
     57 /** \file
     58  * This file has basic file, random, string, list functions
     59  *
     60  * There are 2 types of lists: char** and void**
     61  *
     62  * The *S (not i*S) functions duplicate the parameters and results.
     63  * You must free the result if result is non-NULL and free the parameters
     64  *
     65  * The functions starting with i*S are in place functions.
     66  *
     67  * In Place functions: iList*S and i*S
     68  * The iList*S and i*S functions modify the input buffers
     69  * The input buffers must be allocated with malloc/calloc
     70  * Returns are pointers to original buffers
     71  *
     72  * buffer functions: b*, bL*
     73  * In these functions, the destination buffer is allocated by the caller
     74  * In the bL* functions, the destination size is the size of the buffer (strlen+1)
     75  *
     76  * Ignore case functions: ic*
     77  *
     78  * UTF-8 functions: *UTF8
     79  * Rune is defined as single UTF-8 code point.
     80  *
     81  * libsheepy.h also has:
     82  * - loops: range*, forEach*, linked list forEach (lForEach)
     83  * - arrays: slice, vector, staticArray, indexer, ring, dArray, slab
     84  *
     85  * It is advised to use the C11 generics from libsheepyObject.h instead of the libsheepy.h functions directly because there are many functions.
     86  *
     87  * If you want to add a prefix for libsheepy functions, define a macro
     88  * like this:
     89  * #define SH_PREFIX(NAME) MY_PREFIX ## NAME
     90  *
     91  * Error from any function returning a status have 0, false or NULL for value
     92  * (or specifed otherwise in the function description).
     93  * Errors are reported when the parameters are NULL or invalid, when it happens no parameters and no data stuctures are freed or changed.
     94  * Errors are detected with if (!func)
     95  *
     96  * For more information, the documentation is located at http://spartatek.se/libsheepy/
     97  */
     98 
     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.20"
    102 
    103 #ifndef SH_PREFIX
    104 #define SH_PREFIX(NAME) NAME
    105 #endif
    106 
    107 // libsheepy API Header file _libsheepyH
    108 
    109 /** file internal declarations */
    110 #define internal static
    111 
    112 /** file local declarations (same as internal, shorter word) */
    113 #define local static
    114 
    115 /** declare variable type automaticaly: var a = ARGC; */
    116 #define var __auto_type
    117 
    118 /** type bool true (glibc true is not bool), for use in generics */
    119 #undef TRUE /* avoid conflict with ncurses */
    120 extern const bool TRUE;
    121 /** type bool false (glibc true is not bool), for use in generics */
    122 #undef FALSE /* avoid conflict with ncurses */
    123 extern const bool FALSE;
    124 
    125 /** convenience defines */
    126 #define null NULL
    127 #define yes true
    128 #define on true
    129 #define no false
    130 #define off false
    131 
    132 /** bool to const string: printf("%s\n", boolS(boolValue)); */
    133 #define boolS(x) x ? "TRUE" : "FALSE"
    134 
    135 /**
    136  * success
    137  */
    138 #define XSUCCESS exit(EXIT_SUCCESS);
    139 #define XSuccess XSUCCESS
    140 
    141 /**
    142  * failure
    143  */
    144 #define XFAILURE exit(EXIT_FAILURE);
    145 #define XFailure XFAILURE
    146 
    147 /**
    148  * log string with logP and exit with success
    149  *
    150  * This is useful to know at which line a program exits
    151  */
    152 #define logXSuccess(string) MACRO(\
    153     logP("Success: %s", string);\
    154     XSuccess;\
    155   )
    156 
    157 /**
    158  * log formated string with logP and exit with success
    159  *
    160  * This is useful to know at which line a program exits
    161  * The format string is printed as given, "Success" is not added unlike
    162  * logXSuccess
    163  */
    164 #define logXSuccessf(format, ...) MACRO(\
    165     logP(format, __VA_ARGS__);\
    166     XSuccess;\
    167   )
    168 
    169  /**
    170 - * log string with logC and exit with failure
    171   *
    172   * This is useful to know at which line a program exits
    173   */
    174 #define logXFailure(string) MACRO(\
    175     logC("Failed: %s", string);\
    176      XFailure;\
    177    )
    178 
    179 /**
    180  * log formated string with logC and exit with failure
    181  *
    182  * This is useful to know at which line a program exits
    183  * The format string is printed as given, "Failed" is not added unlike
    184  * logXFailure
    185  */
    186 #define logXFailuref(format, ...) MACRO(\
    187     logC(format, __VA_ARGS__);\
    188     XFailure;\
    189   )
    190 
    191 /**
    192  * log string with logI and exit with exitCode
    193  *
    194  * This is useful to know at which line a program exits
    195  */
    196 #define logExit(exitCode, string) MACRO (\
    197     logI("Exit: %s", string);\
    198     exit(exitCode);\
    199   )
    200 
    201 /**
    202  * exit failure
    203  *
    204  * Exits when cond is false
    205  */
    206 #define exitFailure(cond) \
    207   if (!cond) \
    208     exit(EXIT_FAILURE);
    209 
    210 
    211 /**
    212  * defines for macro begin and end
    213  *
    214  * Macros not returning values are usually written as do while loops:
    215  * #define macro(value) do{
    216  *    puts(value);
    217  *   } while(0)
    218  *
    219  * Using the defines below:
    220  * #define macro(value) procbegin\
    221  *    puts(value);\
    222  *   procend
    223  *
    224  * procbegin and procend are for macros not returning a value (like procedure in pascal)
    225  * funcbegin and funcend are for macros returning a value like functions
    226  *
    227  * Macro returning a value (GNU extension):
    228  * #define macro(value) funcbegin\
    229  *   int returnResult = value + 2;\
    230  *   returnResult;\
    231  *   funcend
    232  */
    233 #define procbegin do{
    234 #define procend   }while(0)
    235 #define funcbegin ({
    236 #define funcend  })
    237 
    238 /**
    239  * do while(0) alternative macro definition
    240  *
    241  * #define macro(param) MACRO( logVarG(param) )
    242  */
    243 #define MACRO( STATEMENTS ) do { STATEMENTS } while(0)
    244 
    245 /**
    246  * Macro returning a value (GNU extension):
    247  * #define macro(value) FUNC(\
    248  *   int returnResult = value + 2;\
    249  *   returnResult;\
    250  *   )
    251  *
    252  */
    253 #define FUNC( STATEMENTS) ({ STATEMENTS })
    254 
    255 /** additions to iso646
    256  * int a is 0;
    257  * if (a equals 1 or a equals 2) a shl = 2;
    258  * else a inc;
    259  * return ptr_to a;
    260  *
    261  * int *b is &a;
    262  * val_of b is a;
    263  * val_of b dec;
    264  */
    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 
    275 /**
    276  * stringify Expression - Turn expression into a string literal
    277  *
    278  * Example:
    279  *   #define PRINT_COND_IF_FALSE(cond) \
    280  *     ((cond) || printf("%s is false!", stringifyExpr(cond)))
    281  */
    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 
    300 /**
    301  * print function name and system error
    302  *
    303  * to print error, use either pFuncError and shEPrintfS
    304  * or shPrintError and shEPrintfS
    305  */
    306 #define pFuncError do{ if ((libsheepyErrorMask) & logMask) { shperror(__func__);logEBtrace;} }while(0);
    307 
    308 /**
    309  * print string and system error
    310  */
    311 #define pStrError(str) do{ if ((libsheepyErrorMask) & logMask) { shperror(str);logEBtrace;} }while(0);
    312 
    313 /**
    314  * print error with line number, function name and file name to stderr
    315  *
    316  * to print error, use either pFuncError and shEPrintfS
    317  * or shPrintError and shEPrintfS
    318  */
    319 #define shPrintError do{ if ((libsheepyErrorMask) & logMask) { logE("Error line "stringifyExpr(__LINE__)", function %s, file "__FILE__"\n", __func__); logEBtrace;} }while(0);
    320 
    321 /**
    322  * print error when function failed. The error code must be -1
    323  */
    324 #define pError(func) if (func == -1) shPrintError
    325 
    326 /**
    327  * print error when function failed. The error code must be 0
    328  */
    329 #define pError0(func) if (func == 0) shPrintError
    330 
    331 /**
    332  * print error when function failed. The error code must be not 0
    333  */
    334 #define pErrorNot0(func) if (func != 0) shPrintError
    335 
    336 /**
    337  * print error when function failed. The error code must be NULL
    338  */
    339 #define pErrorNULL(func) if (func == NULL) shPrintError
    340 
    341 /**
    342  * print error when function failed. The error code must be -1
    343  */
    344 #define pErrorValue(func, errorValue) if (func == errorValue) shPrintError
    345 
    346 /**
    347  * print error when test is true
    348  */
    349 #define pTestError(test) if (test) shPrintError
    350 
    351 /**
    352  * print error and run command when test is true
    353  */
    354 #define pTestErrorCmd(test, cmd) if (test) { shPrintError cmd; }
    355 
    356 /**
    357  * print error and run cmd when test is true
    358  */
    359 #define pErrorCmd(func, test, cmd) if (func test) { shPrintError cmd; }
    360 
    361 /**
    362  * print error when test is true and return func result in result
    363  *
    364  * Example:
    365  *   pErrorResult(k, randomWordF(), == 0)
    366  */
    367 #define pErrorResult(result, func, test) if ((result = func) test) shPrintError
    368 
    369 /**
    370  * print error and run cmd when test is true and return func result in result
    371  *
    372  * Example:
    373  *   pErrorResultCmd(k, randomWordF(), == 0, XFAILURE)
    374   */
    375 #define pErrorResultCmd(result, func, test, cmd) if ((result = func) test) { shPrintError cmd; }
    376 
    377 /**
    378  * is Assigment Error
    379  * catch error when `assigned` is false, 0 or NULL after being assigned with `left`
    380  *
    381  * Example:
    382  * isError(r, malloc(16384)) {
    383  *   return 0;
    384  * }
    385  */
    386 #define isError(assigned, left) if (!(assigned = left))
    387 
    388 /**
    389  * setjmp buffers for try/throw,throwV macros
    390  */
    391 #define maxTryThrowCount 16
    392 extern jmp_buf tryJumpBuffers[maxTryThrowCount];
    393 
    394 /**
    395  * run setjmp using slot in tryJumpBuffers
    396  */
    397 #define setJump(slot) setjmp(tryJumpBuffers[slot])
    398 
    399 /**
    400  * try throw else
    401  * try(slot) saves the environment in slot
    402  * throw(slot) executes the else associated with try(slot)
    403  *
    404  * there are 16 slots
    405  *
    406  * Example:
    407  * try(0) {
    408  *   throw(0);
    409  * }
    410  * else
    411  *   puts("except");
    412  *
    413  */
    414 #define try(slot) if (!setjmp(tryJumpBuffers[slot]))
    415 
    416 /**
    417  * throw goes to else associated with try(slot)
    418  */
    419 #define throw(slot) longjmp(tryJumpBuffers[slot], 1)
    420 
    421 /**
    422  * tryV stores the value from setjmp in result
    423  *
    424  * it is valid to try with throwV and tryV with throw (returns 1)
    425  *
    426  * Example:
    427  */
    428 #define tryV(result, slot) if (!(result = setjmp(tryJumpBuffers[slot])))
    429 
    430 /**
    431  * throwV returns value and goes to else associated with tryV(slot)
    432  */
    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 
    438 /**
    439  * types
    440  */
    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 
    452 /**
    453  * type cast
    454  */
    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 
    475 /**
    476  * get a bitfield in an integer (opposite of FIELD_SET)
    477  */
    478 #define EXTRACT(x, msb, lsb) ((~(0xFFFFFFFFFFFFFFFEUL << (msb)) & (x)) >> (lsb))
    479 
    480 /**
    481  * compare a to b
    482  * a and b have to numbers
    483  *
    484  * \return
    485  *  0  when a equals b
    486  *  -1 when a is less than b
    487  *  1  when a is more than b
    488  */
    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 
    495 /**
    496  * initialize array or struct to zero
    497  *
    498  * int a[10]   = init0Var;
    499  * struct {} s = init0Var;
    500  */
    501 #define init0Var {0}
    502 
    503 /**
    504  * memset array or struct to zero
    505  */
    506 #define ZEROVAR(name) zeroBuf(&(name), sizeof(name))
    507 
    508 /**
    509  * divide count by divider and add one when remainder is not zero
    510  * this is used in segmented arrays to count the number of buckets from the element count
    511  *
    512  * For example, bucket have 64 elements and there are 66 elements in the array
    513  * 66/64 = 1
    514  * and there are 2 buckets, so BUCKETS returns 2
    515  *
    516  * could be:
    517  * (((count) + (1UL<<(divider) -1))/ (divider))
    518  */
    519 #define BUCKETS(count, divider) ((count)/(divider) + (((count) % (divider)) ? 1 : 0))
    520 
    521 /**
    522  * swap a and b, a and b should have the same type
    523  */
    524 #define swapV(a, b) do{\
    525     var UNIQVAR(swaptmp) = a;\
    526     a = b;\
    527     b = UNIQVAR(swaptmp);\
    528   } while(0)
    529 
    530 /** max a,b and store result in result, a and b are evaluated only once */
    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 
    537 /** min a,b and store result in result, a and b are evaluated only once */
    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 
    544 /** max a,b and return result, a and b are evaluated only once */
    545 #define maxV(a, b) ({\
    546     var UNIQVAR(_a) = a;\
    547     var UNIQVAR(_b) = b;\
    548     MAX(UNIQVAR(_a), UNIQVAR(_b));\
    549   })
    550 
    551 /** min a,b and return result, a and b are evaluated only once */
    552 #define minV(a, b) ({\
    553     var UNIQVAR(_a) = a;\
    554     var UNIQVAR(_b) = b;\
    555     MIN(UNIQVAR(_a), UNIQVAR(_b));\
    556   })
    557 
    558 /** absV return absolute value for a, a is evaluated only once*/
    559 #define absV(a) ({var UNIQVAR(_a) = a; ((UNIQVAR(_a)) < 0) ? -(UNIQVAR(_a)) : (UNIQVAR(_a));})
    560 
    561 /**
    562  * FIELD_SIZEOF - get the size of a struct's field
    563  * @t: the target struct
    564  * @f: the target struct's field
    565  * Return: the size of @f in the struct definition without having a
    566  * declared instance of @t.
    567  */
    568 #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
    569 
    570 /** true when value is odd integer */
    571 #define isIntOdd(value) (value&1)
    572 
    573 /** true when value is even integer */
    574 #define isIntEven(value) (!(value&1))
    575 
    576 /**
    577  * typ definition as alternative to typedef
    578  */
    579 #define typ typedef
    580 
    581 /**
    582  * ret definition as alternative to return
    583  */
    584 #define ret return
    585 
    586 /**
    587  * elif definition as alternative to else if
    588  */
    589 #define elif else if
    590 
    591 /**
    592  * unless executes the statement unless the condition is true (that is, if the condition is false).
    593  *
    594  * Example:
    595  * unless(isPath("/void")) {
    596  *   put("the '/void' directory doesn't exist.");
    597  * }
    598  */
    599 #define unless(cond) if(not(cond))
    600 
    601 /**
    602  * until repeats the statement until the condition is true (or while the condition is false)
    603  *
    604  * Example:
    605  * i16 i = 0;
    606  * do {
    607  *   i++;
    608  *   logVarG(i);
    609  * } until(i == 3);
    610  */
    611 #define until(cond) while(not(cond))
    612 
    613 
    614 /**
    615  * define variable and cast pointer
    616  */
    617 #define cast(type, casted, toCast) type casted = (type) (toCast);
    618 
    619 /**
    620  * free pointer and set it to NULL
    621  */
    622 #define freen(ptr) do {\
    623     free(ptr);\
    624     (ptr) = NULL;\
    625   } while(0)
    626 
    627 /**
    628  * Evaluate and assign
    629  * Evaluate, assign result from func and return result using the comma operator
    630  *
    631  * Example:
    632  *  save pointer returned by a function in a function parameter:
    633  *  void *p;
    634  *  func2( EVA(p,func1()) );
    635  *  free(p);
    636  *
    637  *  Using libsheepy functions:
    638  *  char *s;
    639  *  puts( EVA(s, normalizePath("/wef/./../")) );
    640  *  free(s);
    641  */
    642 #define EVA(var, func) (var = func, var)
    643 
    644 /**
    645  * initialize the loop breaker
    646  * declares loop breaker variables
    647  *
    648  * Example:
    649  *
    650  * loopBreakerInit;
    651  * forever {
    652  *   loopBreaker(20);
    653  * }
    654  * if (didBreak) logE("infinite loop detected");
    655  * loopBreakerReset;
    656  * forever {
    657  *   loopBreaker(100);
    658  * }
    659  * if (didBreak) logE("infinite loop detected");
    660  */
    661 #define loopBreakerInit\
    662   uint32_t libsheepyLoopCounter = 0;\
    663   bool didBreak = false;
    664 
    665 /**
    666  * reset the loop breaker variables
    667  */
    668 #define loopBreakerReset\
    669   libsheepyLoopCounter = 0;\
    670   didBreak = false;
    671 
    672 /**
    673  * break the loop when the counter exceed breakCount
    674  */
    675 #define loopBreaker(breakCount)\
    676   libsheepyLoopCounter++;\
    677   if(libsheepyLoopCounter>breakCount){didBreak=true;break;}
    678 
    679 /** generate a string FILE:LINE number
    680  *
    681  * Example:
    682  *   puts(FILE_LINE);
    683  */
    684 #define FILE_LINE __FILE__":"stringifyExpr(__LINE__)
    685 #define PFILE_LINE puts(FILE_LINE)
    686 
    687 /**
    688  * print file, function name and line
    689  *
    690  * Example:
    691  *   AT;
    692  *   libsheepy.c, main:9149
    693  */
    694 #define AT pLog(LOG_DEBUG, __FILE__", %s:"stringifyExpr(__LINE__)"\n",__func__);
    695 
    696 /**
    697  * print a todo message in log
    698  */
    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 
    711 /**
    712  * declare pointer name with type char* and free name when it is out of scope
    713  */
    714 #define cleanCharP(name) char *name CLEANUP(cleanUpCharFree)
    715 
    716 // free val when it is out of scope
    717 void cleanUpListFree(char*** val);
    718 
    719 /**
    720  * declare pointer name with type char* and free name when it is out of scope
    721  */
    722 #define cleanListP(name) char **name CLEANUP(cleanUpListFree)
    723 
    724 // free val when it is out of scope
    725 void cleanUpVoidFree(void **val);
    726 
    727 /**
    728  * declare pointer name with type void* and free name when it is out of scope
    729  */
    730 #define cleanVoidP(name) void *name CLEANUP(cleanUpVoidFree)
    731 
    732 // free val when it is out of scope
    733 void cleanUpFileFree(FILE **val);
    734 
    735 /**
    736  * declare pointer name with type FILE and free (close) name when it is out of scope
    737  */
    738 #define cleanFileP(name) FILE *name CLEANUP(cleanUpFileFree)
    739 
    740 // close val when it is out of scope
    741 void cleanUpFd(int *val);
    742 
    743 /**
    744  * declare a file descriptor name and close name when it is out of scope
    745  */
    746 #define cleanFd(name) int name CLEANUP(cleanUpFd)
    747 #define cleanFdInit(name) int name CLEANUP(cleanUpFd) = -1
    748 
    749 /**
    750  * log variable and its value
    751  *
    752  * Example:
    753  *   logVar(k, PRIu64)
    754  *   k=14
    755  */
    756 #define logVar(var, format) logD("%s=%" format, stringifyExpr(var), var);
    757 #define logMVar(mask, var, format) logMD(mask, "%s=%" format, stringifyExpr(var), var);
    758 
    759 /** log bool variable */
    760 #define logBoolVar(var) logVar(var, "b");
    761 #define logMBoolVar(mask, var) logMVar(mask, var, "b");
    762 
    763 /**
    764  * log pointer
    765  */
    766 #define logPtr(pointer) logD("%s=%p", stringifyExpr(pointer), pointer);
    767 #define logMPtr(mask, pointer) logMD(mask, "%s=%p", stringifyExpr(pointer), pointer);
    768 
    769 // colors and effects
    770 /** reset for color function */
    771 #define RST "\x1B[0m"
    772 /** bold for color function */
    773 #define BLD "\x1B[1m"
    774 /** faint */
    775 #define FNT "\x1B[2m"
    776 /** italic */
    777 #define ITL "\x1B[3m"
    778 /** underline for color function */
    779 #define UDL "\x1B[4m"
    780 /** blink */
    781 #define BLI "\x1B[5m"
    782 /** inverse for color function */
    783 #define INV "\x1B[7m"
    784 /** conceal/hidden for color function */
    785 #define COC "\x1B[8m"
    786 /** crossed for color function */
    787 #define CRD "\x1B[9m"
    788 
    789 // foreground
    790 /** black for color function */
    791 #define BLK "\x1B[30m"
    792 /** red for color function */
    793 #define RED "\x1B[31m"
    794 /** green for color function */
    795 #define GRN "\x1B[32m"
    796 /** yellow for color function */
    797 #define YLW "\x1B[33m"
    798 /** blue for color function */
    799 #define BLU "\x1B[34m"
    800 /** magenta for color function */
    801 #define MGT "\x1B[35m"
    802 /** cyan for color function */
    803 #define CYN "\x1B[36m"
    804 /** white for color function */
    805 #define WHT "\x1B[37m"
    806 
    807 // background
    808 /** bg black for color function */
    809 #define BGBLK "\x1B[40m"
    810 /** bg red for color function */
    811 #define BGRED "\x1B[41m"
    812 /** bg green for color function */
    813 #define BGGRN "\x1B[42m"
    814 /** bg yellow for color function */
    815 #define BGYLW "\x1B[43m"
    816 /** bg blue for color function */
    817 #define BGBLU "\x1B[44m"
    818 /** bg magenta for color function */
    819 #define BGMGT "\x1B[45m"
    820 /** bg cyan for color function */
    821 #define BGCYN "\x1B[46m"
    822 /** bg white for color function */
    823 #define BGWHT "\x1B[47m"
    824 
    825 // bug in cg_c.py
    826 #define sheepyRGBFP len = fprintf(stream, "%*s", (int)(info->left ? -info->width : info->width), b)
    827 #define sheepyBOOLFP len = fprintf(stream, "%*s", (int)(info->left ? -info->width : info->width), boolS(value))
    828 
    829 /**
    830  * time a function in nanoseconds
    831  *
    832  * Example:
    833  * timeNs(func(anInt));
    834  */
    835 #define timeNs(func) do{\
    836   u64 UNIQVAR(endTime);\
    837   u64 UNIQVAR(startTime) = getMonotonicTime();\
    838   func;\
    839   UNIQVAR(endTime) = getMonotonicTime();\
    840   printf(BLD GRN "time" RST ": %" PRIu64 "ns " BLD UDL YLW "%s" RST "\n", UNIQVAR(endTime)-UNIQVAR(startTime), stringifyExpr(func));\
    841 }while(0)
    842 
    843 #define TIMEUNITUS "us"
    844 #define TIMEUNITMS "ms"
    845 #define TIMEUNITSC "s"
    846 
    847 /**
    848  * time a function with div
    849  *
    850  * Example:
    851  * timeDivs(func(anInt), 1E3);
    852  */
    853 #define timeDivs(func, div, timeunit) do{\
    854   u64 UNIQVAR(endTime);\
    855   u64 UNIQVAR(startTime) = getMonotonicTime();\
    856   func;\
    857   UNIQVAR(endTime) = getMonotonicTime();\
    858   printf(BLD GRN "time:" RST " %f"timeunit" " BLD UDL YLW "%s" RST "\n", (f32)(UNIQVAR(endTime)-UNIQVAR(startTime))/div, stringifyExpr(func));\
    859 }while(0)
    860 
    861 /**
    862  * time a function in microseconds
    863  *
    864  * Example:
    865  * timeUs(func(anInt));
    866  */
    867 #define timeUs(func) timeDivs(func,1E3, TIMEUNITUS)
    868 
    869 /**
    870  * time a function in miliseconds
    871  *
    872  * Example:
    873  * timeMs(func(anInt));
    874  */
    875 #define timeMs(func) timeDivs(func,1E6, TIMEUNITMS)
    876 
    877 /**
    878  * time a function in seconds
    879  *
    880  * Example:
    881  * timeSec(func(anInt));
    882  */
    883 #define timeSec(func) timeDivs(func,1E9, TIMEUNITSC)
    884 
    885 // nanosecond stopwatch, the returned value is in ns. op parameter: 0 to start, 1 to get the stopwatch value
    886 uint64_t shStopwatch(uint8_t op);
    887 
    888 #define stopwatchStart shStopwatch(0)
    889 
    890 /**
    891  * print stopwatch value in ns since last start
    892  */
    893 #define stopwatchLog printf(BLD GRN "time" RST ": %" PRIu64 "ns\n", shStopwatch(1))
    894 
    895 /**
    896  * print stopwatch value in provided unit since last start
    897  */
    898 #define stopwatchLogDivs(div, timeunit) printf(BLD GRN "time" RST ": %f"timeunit"\n", ((float)shStopwatch(1))/div)
    899 
    900 /**
    901  * print stopwatch value in microseconds since last start
    902  */
    903 #define stopwatchLogUs stopwatchLogDivs(1E3, TIMEUNITUS)
    904 
    905 /**
    906  * print stopwatch value in milliseconds since last start
    907  */
    908 #define stopwatchLogMs stopwatchLogDivs(1E6, TIMEUNITMS)
    909 
    910 /**
    911  * print stopwatch value in seconds since last start
    912  */
    913 #define stopwatchLogSec stopwatchLogDivs(1E9, TIMEUNITSC)
    914 
    915 /**
    916  * LOG LEVELS
    917  * Note: When adding log levels or modes, the log_tags array in libsheepy.c
    918  *       must be updated.
    919  */
    920 #define LOG_EMERGENCY 0
    921 #define LOG_ALERT     1
    922 #define LOG_CRITICAL  2
    923 #define LOG_ERROR     3
    924 #ifdef LOG_WARNING
    925 #undef LOG_WARNING // conflict with syslog.h
    926 #endif
    927 #define LOG_WARNING   4
    928 #define LOG_NOTICE    5
    929 #define LOG_PASS      6
    930 #ifdef LOG_INFO
    931 #undef LOG_INFO // conflict with syslog.h
    932 #endif
    933 #define LOG_INFO      7
    934 #define LOG_DEBUG     8
    935 #define LOG_INVALID   9
    936 #define LOG_MAX_LEVEL LOG_INVALID
    937 
    938 /** getMaxLogLevel and setMaxLogLevel value disabling all logs */
    939 #define LOG_DISABLE -1
    940 
    941 /**
    942  * LOG MODES
    943  * when a new mode is added, add symbols in log_tags in libsheepy.c
    944  */
    945 
    946 /**
    947  * log symbol, program name, filename, function, line, date
    948  */
    949 #define LOG_VERBOSE       0
    950 
    951 /**
    952  * log symbol
    953  */
    954 #define LOG_CONCISE       1
    955 
    956 /**
    957  * log symbol and date
    958  */
    959 #define LOG_DATE          2 // default
    960 
    961 /**
    962  * log symbol and function
    963  */
    964 #define LOG_FUNC          3
    965 
    966 /**
    967  * log symbol and program name
    968  */
    969 #define LOG_PROG          4
    970 
    971 /**
    972  * log symbol, program name and date
    973  */
    974 #define LOG_PROGNDATE     5
    975 
    976 /**
    977  * log message only
    978  */
    979 #define LOG_VOID          6
    980 
    981 /**
    982  * UTF8 symbols and concise
    983  */
    984 #define LOG_UTF8          7
    985 
    986 /**
    987  * log symbol, program name and function
    988  */
    989 #define LOG_PROGNFUNC     8
    990 
    991 /**
    992  * invalid
    993  */
    994 #define LOG_INVALID_MODE  9
    995 
    996 // add a log file, maximum 15 files
    997 FILE *SH_PREFIX(setLogFile)(char *filename);
    998 #define openLogFile setLogFile
    999 
   1000 #ifdef __GNUC__
   1001 /** force function callers to check return value
   1002  * The warning is disabled with -Wno-unused-result (default in sheepy config ~/.sheepy/config.yml
   1003  * Enable this warning to make all errors caught as early as possible and handled correctly.
   1004  */
   1005 #define MUST_CHECK    __attribute__ ((warn_unused_result))
   1006 #else
   1007 #define MUST_CHECK
   1008 #endif
   1009 
   1010 // current log symbols
   1011 int getLogSymbols(void) MUST_CHECK;
   1012 
   1013 // 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 (!*+->~)
   1014 void setLogSymbols(int mode);
   1015 
   1016 // current max log level
   1017 int getMaxLogLevel(void) MUST_CHECK;
   1018 
   1019 // set max log level, logs above logMaxLevel are skipped
   1020 void setMaxLogLevel(int logLevel);
   1021 
   1022 // close logfiles opened with setLogFile
   1023 void closeLogFiles(void);
   1024 
   1025 // get current log mode (LOG_VERBOSE, LOG_CONCISE, ...)
   1026 int getLogMode(void) MUST_CHECK;
   1027 
   1028 // set log mode LOG_VERBOSE, LOG_CONCISE, ...
   1029 void setLogMode(int mode);
   1030 
   1031 // get current log long/short path value, default is TRUE (short paths)
   1032 bool getLogShortPath(void) MUST_CHECK;
   1033 
   1034 // set log long/short file path value for VERBOSE mode
   1035 void setLogShortPath(bool shortPath);
   1036 
   1037 // get stdout state, when TRUE (default) all logs are printed to stdout
   1038 bool getLogStdout(void) MUST_CHECK;
   1039 
   1040 // enable/disable printing logs to stdout
   1041 void setLogStdout(bool state);
   1042 
   1043 // log to a file named progName.log
   1044 bool openProgLogFile(void) MUST_CHECK;
   1045 
   1046 // keep ansi colors in logs
   1047 void keepAnsiColorsInLog(bool state);
   1048 
   1049 /**
   1050  * print logging levels
   1051  *
   1052  * to disable logging, empty pLog define:
   1053  * #undef pLog
   1054  * #define pLog
   1055  *
   1056  * \param
   1057  *   level LOG_CRITICAL, LOG_ERROR, LOG_WARNING or LOG_INFO, anything else has log level LOG_INVALID
   1058  * \param
   1059  *   message like printf
   1060  */
   1061 #define pLog(level, ...) _pLog(level, __FILE__, __func__, __LINE__, __VA_ARGS__);
   1062 
   1063 void _pLog(int, const char *, const char *, int, const char *, ...);
   1064 
   1065 #define logY(...) pLog(LOG_EMERGENCY, __VA_ARGS__)
   1066 #define logA(...) pLog(LOG_ALERT, __VA_ARGS__)
   1067 #define logC(...) pLog(LOG_CRITICAL, __VA_ARGS__)
   1068 #define logE(...) pLog(LOG_ERROR, __VA_ARGS__)
   1069 #define logW(...) pLog(LOG_WARNING, __VA_ARGS__)
   1070 #define logN(...) pLog(LOG_NOTICE, __VA_ARGS__)
   1071 #define logP(...) pLog(LOG_PASS, __VA_ARGS__)
   1072 #define logI(...) pLog(LOG_INFO, __VA_ARGS__)
   1073 #define logD(...) pLog(LOG_DEBUG, __VA_ARGS__)
   1074 
   1075 /**
   1076  * log string and free
   1077  * Example:
   1078  * logSY("The list: %s", catS("1", "2"));
   1079  */
   1080 #define logSY(format, string) do {\
   1081     char *libsheepyInternalString = string;\
   1082     logY(format, libsheepyInternalString);\
   1083     free(libsheepyInternalString);\
   1084   } while(0)
   1085 
   1086 /**
   1087  * log string and free
   1088  * Example:
   1089  * logSA("The list: %s", catS("1", "2"));
   1090  */
   1091 #define logSA(format, string) do {\
   1092     char *libsheepyInternalString = string;\
   1093     logA(format, libsheepyInternalString);\
   1094     free(libsheepyInternalString);\
   1095   } while(0)
   1096 
   1097 /**
   1098  * log string and free
   1099  * Example:
   1100  * logSC("The list: %s", catS("1", "2"));
   1101  */
   1102 #define logSC(format, string) do {\
   1103     char *libsheepyInternalString = string;\
   1104     logC(format, libsheepyInternalString);\
   1105     free(libsheepyInternalString);\
   1106   } while(0)
   1107 
   1108 /**
   1109  * log string and free
   1110  * Example:
   1111  * logSE("The list: %s", catS("1", "2"));
   1112  */
   1113 #define logSE(format, string) do {\
   1114     char *libsheepyInternalString = string;\
   1115     logE(format, libsheepyInternalString);\
   1116     free(libsheepyInternalString);\
   1117   } while(0)
   1118 
   1119 /**
   1120  * log string and free
   1121  * Example:
   1122  * logSW("The list: %s", catS("1", "2"));
   1123  */
   1124 #define logSW(format, string) do {\
   1125     char *libsheepyInternalString = string;\
   1126     logW(format, libsheepyInternalString);\
   1127     free(libsheepyInternalString);\
   1128   } while(0)
   1129 
   1130 /**
   1131  * log string and free
   1132  * Example:
   1133  * logSN("The list: %s", catS("1", "2"));
   1134  */
   1135 #define logSN(format, string) do {\
   1136     char *libsheepyInternalString = string;\
   1137     logN(format, libsheepyInternalString);\
   1138     free(libsheepyInternalString);\
   1139   } while(0)
   1140 
   1141 /**
   1142  * log string and free
   1143  * Example:
   1144  * logSP("The list: %s", catS("1", "2"));
   1145  */
   1146 #define logSP(format, string) do {\
   1147     char *libsheepyInternalString = string;\
   1148     logP(format, libsheepyInternalString);\
   1149     free(libsheepyInternalString);\
   1150   } while(0)
   1151 
   1152 /**
   1153  * log string and free
   1154  * Example:
   1155  * logSI("The list: %s", catS("1", "2"));
   1156  */
   1157 #define logSI(format, string) do {\
   1158     char *libsheepyInternalString = string;\
   1159     logI(format, libsheepyInternalString);\
   1160     free(libsheepyInternalString);\
   1161   } while(0)
   1162 
   1163 /**
   1164  * log string and free
   1165  * Example:
   1166  * logSD("The list: %s", catS("1", "2"));
   1167  */
   1168 #define  logSD(format, string) do {\
   1169     char *libsheepyInternalString = string;\
   1170     logD(format, libsheepyInternalString);\
   1171     free(libsheepyInternalString);\
   1172   } while(0)
   1173 
   1174 
   1175 /** variable to control which group logs to show, all logs are enabled by default (0xFFFFFFFFFFFFFFFF) */
   1176 extern uint64_t logMask;
   1177 
   1178 /**
   1179  * print mask logging levels
   1180  *
   1181  * print logs with a mask in logMask
   1182  * normally, mask is 1 bit wide.
   1183  *
   1184  * pLogMask allows enabling/disabling groups of logs
   1185  *
   1186  * to disable logging, empty pLogMask define:
   1187  * #undef pLogMask
   1188  * #define pLogMask
   1189  *
   1190  * Example:
   1191  *
   1192  * #define group1 0x03
   1193  * #define group11 0x01
   1194  * #define group12 0x02
   1195  * #define group2 0x04
   1196  *
   1197  * logMask = group11;
   1198  * logMI(group1, "is shown when logMask has bit 0 or 1 set");
   1199  * logMI(group11, "is shown when logMask has bit 0 set");
   1200  * logMI(group12, "is shown when logMask has bit 1 set");
   1201  * logMI(group2, "is shown when logMask has bit 2 set");
   1202  *
   1203  * \param
   1204  *   level LOG_CRITICAL, LOG_ERROR, LOG_WARNING or LOG_INFO, anything else has log level LOG_INVALID
   1205  * \param
   1206  *   message like printf
   1207  */
   1208 #define pLogMask(mask, level, ...) if ((mask) & logMask) pLog(level, __VA_ARGS__)
   1209 
   1210 #define logMY(mask, ...) pLogMask(mask, LOG_EMERGENCY, __VA_ARGS__)
   1211 #define logMA(mask, ...) pLogMask(mask, LOG_ALERT, __VA_ARGS__)
   1212 #define logMC(mask, ...) pLogMask(mask, LOG_CRITICAL, __VA_ARGS__)
   1213 #define logME(mask, ...) pLogMask(mask, LOG_ERROR, __VA_ARGS__)
   1214 #define logMW(mask, ...) pLogMask(mask, LOG_WARNING, __VA_ARGS__)
   1215 #define logMN(mask, ...) pLogMask(mask, LOG_NOTICE, __VA_ARGS__)
   1216 #define logMP(mask, ...) pLogMask(mask, LOG_PASS, __VA_ARGS__)
   1217 #define logMI(mask, ...) pLogMask(mask, LOG_INFO, __VA_ARGS__)
   1218 #define logMD(mask, ...) pLogMask(mask, LOG_DEBUG, __VA_ARGS__)
   1219 
   1220 // show log messages in mask
   1221 #define showLogsInMask(mask) logMask |= mask
   1222 
   1223 // hide log messages in mask
   1224 #define hideLogsInMask(mask) logMask &= ~(mask)
   1225 
   1226 /**
   1227  * log and mask string and then free
   1228  * Example:
   1229  * logSMY("The list: %s", catS("1", "2"));
   1230  */
   1231 #define logSMY(mask, format, string) do {\
   1232     char *libsheepyInternalString = string;\
   1233     logMY(mask, format, libsheepyInternalString);\
   1234     free(libsheepyInternalString);\
   1235   } while(0)
   1236 
   1237 /**
   1238  * log and mask string and then free
   1239  * Example:
   1240  * logSMA("The list: %s", catS("1", "2"));
   1241  */
   1242 #define logSMA(mask, format, string) do {\
   1243     char *libsheepyInternalString = string;\
   1244     logMA(mask, format, libsheepyInternalString);\
   1245     free(libsheepyInternalString);\
   1246   } while(0)
   1247 
   1248 /**
   1249  * log and mask string and then free
   1250  * Example:
   1251  * logSMI("The list: %s", catS("1", "2"));
   1252  */
   1253 #define logSMC(mask, format, string) do {\
   1254     char *libsheepyInternalString = string;\
   1255     logMC(mask, format, libsheepyInternalString);\
   1256     free(libsheepyInternalString);\
   1257   } while(0)
   1258 
   1259 /**
   1260  * log and mask string and then free
   1261  * Example:
   1262  * logSME("The list: %s", catS("1", "2"));
   1263  */
   1264 #define logSME(mask, format, string) do {\
   1265     char *libsheepyInternalString = string;\
   1266     logME(mask, format, libsheepyInternalString);\
   1267     free(libsheepyInternalString);\
   1268   } while(0)
   1269 
   1270 /**
   1271  * log and mask string and then free
   1272  * Example:
   1273  * logSMW("The list: %s", catS("1", "2"));
   1274  */
   1275 #define logSMW(mask, format, string) do {\
   1276     char *libsheepyInternalString = string;\
   1277     logMW(mask, format, libsheepyInternalString);\
   1278     free(libsheepyInternalString);\
   1279   } while(0)
   1280 
   1281 /**
   1282  * log and mask string and then free
   1283  * Example:
   1284  * logSMN("The list: %s", catS("1", "2"));
   1285  */
   1286 #define logSMN(mask, format, string) do {\
   1287     char *libsheepyInternalString = string;\
   1288     logMN(mask, format, libsheepyInternalString);\
   1289     free(libsheepyInternalString);\
   1290   } while(0)
   1291 
   1292 /**
   1293  * log and mask string and then free
   1294  * Example:
   1295  * logSMP("The list: %s", catS("1", "2"));
   1296  */
   1297 #define logSMP(mask, format, string) do {\
   1298     char *libsheepyInternalString = string;\
   1299     logMP(mask, format, libsheepyInternalString);\
   1300     free(libsheepyInternalString);\
   1301   } while(0)
   1302 
   1303 /**
   1304  * log and mask string and then free
   1305  * Example:
   1306  * logSMI("The list: %s", catS("1", "2"));
   1307  */
   1308 #define logSMI(mask, format, string) do {\
   1309     char *libsheepyInternalString = string;\
   1310     logMI(mask, format, libsheepyInternalString);\
   1311     free(libsheepyInternalString);\
   1312   } while(0)
   1313 
   1314 /**
   1315  * log and mask string and then free
   1316  * Example:
   1317  * logSMD("The list: %s", catS("1", "2"));
   1318  */
   1319 #define logSMD(mask, format, string) do {\
   1320     char *libsheepyInternalString = string;\
   1321     logMD(mask, format, libsheepyInternalString);\
   1322     free(libsheepyInternalString);\
   1323   } while(0)
   1324 
   1325 // QSORT
   1326 
   1327 /*
   1328  * Copyright (c) 2013, 2017 Alexey Tourbin
   1329  *
   1330  * Permission is hereby granted, free of charge, to any person obtaining a copy
   1331  * of this software and associated documentation files (the "Software"), to deal
   1332  * in the Software without restriction, including without limitation the rights
   1333  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   1334  * copies of the Software, and to permit persons to whom the Software is
   1335  * furnished to do so, subject to the following conditions:
   1336  *
   1337  * The above copyright notice and this permission notice shall be included in
   1338  * all copies or substantial portions of the Software.
   1339  *
   1340  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   1341  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   1342  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
   1343  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   1344  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   1345  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   1346  * SOFTWARE.
   1347  */
   1348 
   1349 /*
   1350  * https://github.com/svpv/qsort.git
   1351  * commit 21f056356e901467b7362240dac70edeedfa2b89
   1352  */
   1353 
   1354 /*
   1355  * This is a traditional Quicksort implementation which mostly follows
   1356  * [Sedgewick 1978].  Sorting is performed entirely on array indices,
   1357  * while actual access to the array elements is abstracted out with the
   1358  * user-defined `LESS` and `SWAP` primitives.
   1359  *
   1360  * Synopsis:
   1361  *	QSORT(N, LESS, SWAP);
   1362  * where
   1363  *	N - the number of elements in A[];
   1364  *	LESS(i, j) - compares A[i] to A[j];
   1365  *	SWAP(i, j) - exchanges A[i] with A[j].
   1366  *
   1367  * Examples:
   1368  * - int array:
   1369  * int A[] = {3,2,1};
   1370  * int tmp;
   1371  *
   1372  * #define LESS(i, j) A[i] < A[j]
   1373  * #define SWAP(i, j) tmp = A[i], A[i] = A[j], A[j] = tmp
   1374  *
   1375  * QSORT(3, LESS, SWAP);
   1376  * #undef LESS
   1377  * #undef SWAP
   1378  *
   1379  *
   1380  * - string array/list:
   1381  * char **strs = listCreateS("fsd", "sdf", "ffds","asd");
   1382  * char *tmp;
   1383  *
   1384  * #define LESS(i,j) (strcmp(strs[i], strs[j]) < 0)
   1385  * #define SWAP(i,j) tmp = strs[i], strs[i] = strs[j], strs[j] = tmp
   1386  *
   1387  * QSORT(listLengthS(strs), LESS, SWAP);
   1388  * #undef LESS
   1389  * #undef SWAP
   1390  *
   1391  */
   1392 
   1393 /* Sort 3 elements. */
   1394 #define Q_SORT3(q_a1, q_a2, q_a3, Q_LESS, Q_SWAP) do {\
   1395     if (Q_LESS(q_a2, q_a1)) {\
   1396       if (Q_LESS(q_a3, q_a2))\
   1397         Q_SWAP(q_a1, q_a3);\
   1398       else {\
   1399         Q_SWAP(q_a1, q_a2);\
   1400         if (Q_LESS(q_a3, q_a2))\
   1401           Q_SWAP(q_a2, q_a3);\
   1402       }\
   1403     }\
   1404     else if (Q_LESS(q_a3, q_a2)) {\
   1405       Q_SWAP(q_a2, q_a3);\
   1406       if (Q_LESS(q_a2, q_a1))\
   1407         Q_SWAP(q_a1, q_a2);	\
   1408     }\
   1409   } while (0)
   1410 
   1411 /* Partition [q_l,q_r] around a pivot.  After partitioning,
   1412  * [q_l,q_j] are the elements that are less than or equal to the pivot,
   1413  * while [q_i,q_r] are the elements greater than or equal to the pivot. */
   1414 #define Q_PARTITION(q_l, q_r, q_i, q_j, Q_UINT, Q_LESS, Q_SWAP)	do {\
   1415     /* The middle element, not to be confused with the median. */\
   1416     Q_UINT UNIQVAR(q_m) = q_l + ((q_r - q_l) >> 1);\
   1417     /* Reorder the second, the middle, and the last items.\
   1418      * As [Edelkamp Weiss 2016] explain, using the second element\
   1419      * instead of the first one helps avoid bad behaviour for\
   1420      * decreasingly sorted arrays.  This method is used in recent\
   1421      * versions of gcc's std::sort, see gcc bug 58437#c13, although\
   1422      * the details are somewhat different (cf. #c14). */\
   1423     Q_SORT3(q_l + 1, UNIQVAR(q_m), q_r, Q_LESS, Q_SWAP);\
   1424     /* Place the median at the beginning. */\
   1425     Q_SWAP(q_l, UNIQVAR(q_m));\
   1426     /* Partition [q_l+2, q_r-1] around the median which is in q_l.\
   1427      * q_i and q_j are initially off by one, they get decremented\
   1428      * in the do-while loops. */\
   1429     q_i = q_l + 1; q_j = q_r;\
   1430     while (1) {\
   1431       do q_i++; while (Q_LESS(q_i, q_l));\
   1432       do q_j--; while (Q_LESS(q_l, q_j));\
   1433       if (q_i >= q_j) break; /* Sedgewick says "until j < i" */\
   1434       Q_SWAP(q_i, q_j);\
   1435     }\
   1436     /* Compensate for the i==j case. */\
   1437     q_i = q_j + 1;\
   1438     /* Put the median to its final place. */\
   1439     Q_SWAP(q_l, q_j);\
   1440     /* The median is not part of the left subfile. */\
   1441     q_j--;\
   1442   } while (0)
   1443 
   1444 /* Insertion sort is applied to small subfiles - this is contrary to
   1445  * Sedgewick's suggestion to run a separate insertion sort pass after
   1446  * the partitioning is done.  The reason I don't like a separate pass
   1447  * is that it triggers extra comparisons, because it can't see that the
   1448  * medians are already in their final positions and need not be rechecked.
   1449  * Since I do not assume that comparisons are cheap, I also do not try
   1450  * to eliminate the (q_j > q_l) boundary check. */
   1451 #define Q_INSERTION_SORT(q_l, q_r, Q_UINT, Q_LESS, Q_SWAP) do {\
   1452     Q_UINT UNIQVAR(q_i), UNIQVAR(q_j);\
   1453     /* For each item starting with the second... */\
   1454     for (UNIQVAR(q_i) = q_l + 1; UNIQVAR(q_i) <= q_r; UNIQVAR(q_i)++)\
   1455     /* move it down the array so that the first part is sorted. */\
   1456     for (UNIQVAR(q_j) = UNIQVAR(q_i); UNIQVAR(q_j) > q_l && (Q_LESS(UNIQVAR(q_j), UNIQVAR(q_j) - 1)); UNIQVAR(q_j)--)\
   1457       Q_SWAP(UNIQVAR(q_j), UNIQVAR(q_j) - 1);\
   1458   } while (0)
   1459 
   1460 /* When the size of [q_l,q_r], i.e. q_r-q_l+1, is greater than or equal to
   1461  * Q_THRESH, the algorithm performs recursive partitioning.  When the size
   1462  * drops below Q_THRESH, the algorithm switches to insertion sort.
   1463  * The minimum valid value is probably 5 (with 5 items, the second and
   1464  * the middle items, the middle itself being rounded down, are distinct). */
   1465 #define Q_THRESH 16
   1466 
   1467 /* The main loop. */
   1468 #define Q_LOOP(Q_UINT, Q_N, Q_LESS, Q_SWAP) do {\
   1469     Q_UINT UNIQVAR(q_l) = 0;\
   1470     Q_UINT UNIQVAR(q_r) = (Q_N) - 1;\
   1471     Q_UINT UNIQVAR(q_sp) = 0; /* the number of frames pushed to the stack */\
   1472     struct { Q_UINT q_l, q_r; }\
   1473     /* On 32-bit platforms, to sort a "char[3GB+]" array,\
   1474      * it may take full 32 stack frames.  On 64-bit CPUs,\
   1475      * though, the address space is limited to 48 bits.\
   1476      * The usage is further reduced if Q_N has a 32-bit type. */\
   1477     UNIQVAR(q_st)[sizeof(Q_UINT) > 4 && sizeof(Q_N) > 4 ? 48 : 32];\
   1478     while (1) {\
   1479       if (UNIQVAR(q_r) - UNIQVAR(q_l) + 1 >= Q_THRESH) {\
   1480         Q_UINT UNIQVAR(q_i), UNIQVAR(q_j);\
   1481         Q_PARTITION(UNIQVAR(q_l), UNIQVAR(q_r), UNIQVAR(q_i), UNIQVAR(q_j), Q_UINT, Q_LESS, Q_SWAP);\
   1482         /* Now have two subfiles: [q_l,q_j] and [q_i,q_r].\
   1483          * Dealing with them depends on which one is bigger. */\
   1484         if (UNIQVAR(q_j) - UNIQVAR(q_l) >= UNIQVAR(q_r) - UNIQVAR(q_i))\
   1485           Q_SUBFILES(UNIQVAR(q_l), UNIQVAR(q_j), UNIQVAR(q_i), UNIQVAR(q_r));\
   1486         else\
   1487           Q_SUBFILES(UNIQVAR(q_i), UNIQVAR(q_r), UNIQVAR(q_l), UNIQVAR(q_j));\
   1488       }\
   1489       else {\
   1490         Q_INSERTION_SORT(UNIQVAR(q_l), UNIQVAR(q_r), Q_UINT, Q_LESS, Q_SWAP);\
   1491         /* Pop subfiles from the stack, until it gets empty. */\
   1492         if (UNIQVAR(q_sp) == 0) break;\
   1493         UNIQVAR(q_sp)--;\
   1494         UNIQVAR(q_l) = UNIQVAR(q_st)[UNIQVAR(q_sp)].q_l;\
   1495         UNIQVAR(q_r) = UNIQVAR(q_st)[UNIQVAR(q_sp)].q_r;\
   1496       }\
   1497     }\
   1498   } while (0)
   1499 
   1500 /* The missing part: dealing with subfiles.
   1501  * Assumes that the first subfile is not smaller than the second. */
   1502 #define Q_SUBFILES(q_l1, q_r1, q_l2, q_r2) do {\
   1503     /* If the second subfile is only a single element, it needs\
   1504      * no further processing.  The first subfile will be processed\
   1505      * on the next iteration (both subfiles cannot be only a single\
   1506      * element, due to Q_THRESH). */\
   1507     if (q_l2 == q_r2) {\
   1508       UNIQVAR(q_l) = q_l1;\
   1509       UNIQVAR(q_r) = q_r1;\
   1510     }\
   1511     else {\
   1512       /* Otherwise, both subfiles need processing.\
   1513        * Push the larger subfile onto the stack. */\
   1514       UNIQVAR(q_st)[UNIQVAR(q_sp)].q_l = q_l1;\
   1515       UNIQVAR(q_st)[UNIQVAR(q_sp)].q_r = q_r1;\
   1516       UNIQVAR(q_sp)++;\
   1517       /* Process the smaller subfile on the next iteration. */\
   1518       UNIQVAR(q_l) = q_l2;\
   1519       UNIQVAR(q_r) = q_r2;\
   1520     }\
   1521   } while (0)
   1522 
   1523 /* And now, ladies and gentlemen, may I proudly present to you... */
   1524 #define QSORT(Q_N, Q_LESS, Q_SWAP) do {\
   1525     if ((Q_N) > 1) {\
   1526       if (sizeof(Q_N) == sizeof(unsigned long)) {\
   1527         Q_LOOP(unsigned long, Q_N, Q_LESS, Q_SWAP);}\
   1528       else if (sizeof(Q_N) <= sizeof(unsigned)) {\
   1529         Q_LOOP(unsigned, Q_N, Q_LESS, Q_SWAP);}\
   1530     }\
   1531   } while (0)
   1532 
   1533 // QSORT END
   1534 
   1535 // BINARY SEARCH
   1536 
   1537 /**
   1538  * binary search macro
   1539  *
   1540  * Synopsis:
   1541  *	BSEARCH(RESULT_INDEX, SEARCH_ELEMENT, N, LESS, EQUAL);
   1542  * where
   1543  *  RESULT_INDEX             - variable holding the result index, signed int type (example: ssize_t),
   1544  *                             declare RESULT_INDEX before calling BSEARCH;
   1545  *  SEARCH_ELEMENT           - element to search in the array;
   1546  *	N                        - the number of elements in A[];
   1547  *	LESS(i, SEARCH_ELEMENT)  - compares A[i] to SEARCH_ELEMENT, 1 when less;
   1548  *	EQUAL(i, SEARCH_ELEMENT) - compares A[i] to SEARCH_ELEMENT, 1 when equal;
   1549  *
   1550  * Example:
   1551  * int A[] = {1,5,7,9,10,65};
   1552  * ssize_t bsr;
   1553  *
   1554  * #define LESS(i, se) A[i] < se
   1555  * #define EQUAL(i, se) A[i] == se
   1556  * BSEARCH(bsr, 9, COUNT_ELEMENTS(A), LESS, EQUAL);
   1557  * #undef LESS
   1558  * #undef EQUAL
   1559  *
   1560  * logVar(bsr,"zd");
   1561  *
   1562  */
   1563 #define BSEARCH(RESULT_INDEX, SEARCH_ELEMENT, B_N, B_LESS, B_EQUAL) do {\
   1564   ssize_t UNIQVAR(b_first) = 0, UNIQVAR(b_middle), UNIQVAR(b_last);\
   1565   UNIQVAR(b_last) = B_N-1;\
   1566   while (UNIQVAR(b_first) <= UNIQVAR(b_last)) {\
   1567     UNIQVAR(b_middle) = (UNIQVAR(b_first)+UNIQVAR(b_last))/2;\
   1568     if (B_LESS(UNIQVAR(b_middle), SEARCH_ELEMENT)) UNIQVAR(b_first) = UNIQVAR(b_middle) + 1;\
   1569     else if (B_EQUAL(UNIQVAR(b_middle), SEARCH_ELEMENT)) {\
   1570       RESULT_INDEX = UNIQVAR(b_middle);\
   1571       goto UNIQVAR(end);\
   1572     }\
   1573     else UNIQVAR(b_last) = UNIQVAR(b_middle) -1;\
   1574   }\
   1575   /* element not found */\
   1576   RESULT_INDEX = -1;\
   1577   UNIQVAR(end):;\
   1578   } while(0)
   1579 
   1580 // BINARY SEARCH END
   1581 
   1582 // makeRoom is dynamic memory allocation algorithm
   1583 // given a length, an allocated size and the additionnal length,
   1584 // makeRoom returns the new allocated size for realloc
   1585 // when the new allocated size equals alloc value, there is no need to realloc the memory, enough space is already available
   1586 #define libsheepyPrealloc (1024*1024)
   1587 #define makeRoom(length, alloc, addlength) funcbegin\
   1588     typeof(alloc) r;\
   1589     typeof(alloc) newlen = (length) + (addlength);\
   1590     if (newlen < (alloc)) {\
   1591       r = alloc;\
   1592     } \
   1593     else {\
   1594       if (newlen < libsheepyPrealloc) {\
   1595         r = newlen * 2;\
   1596       }\
   1597       else {\
   1598         r = newlen + libsheepyPrealloc;\
   1599       }\
   1600     }\
   1601     r;\
   1602   funcend
   1603 
   1604 // initialize libsheepy (optional, for debug)
   1605 typedef void(*initLibsheepyObjectP)(void);
   1606 void initLibsheepyF(const char *progPath, initLibsheepyObjectP initF);
   1607 #define initLibsheepy(progPath) initLibsheepyF(progPath, NULL)
   1608 
   1609 // free internal buffers at exit
   1610 void finalizeLibsheepyCharAtExit(void);
   1611 
   1612 // get current stack limit - returns 0 when error
   1613 int64_t getStackLimit(void) MUST_CHECK;
   1614 
   1615 // set stack limit (-1 for unlimited) - returns 0 when error
   1616 int setStackLimit(int64_t stackSize) MUST_CHECK;
   1617 
   1618 // enable core dump
   1619 int enableCoreDump(void) MUST_CHECK;
   1620 
   1621 // get program name
   1622 const char *getProgName(void) MUST_CHECK;
   1623 
   1624 // set program name
   1625 bool setProgName(const char *name) MUST_CHECK;
   1626 
   1627 // set default program name
   1628 void setDefaultProgName(void);
   1629 
   1630 // free ProgName
   1631 void freeProgName(void);
   1632 
   1633 // get program path as given in the shell
   1634 const char *getProgPath(void) MUST_CHECK;
   1635 
   1636 // get real program path, allocates path string internally
   1637 const char *getRealProgPath(void) MUST_CHECK;
   1638 
   1639 // free real program path
   1640 void freeRealProgPath(void);
   1641 
   1642 // run system command and free command buffer
   1643 #define systemNFree(command) systemNFreeF(command, __LINE__, __func__, __FILE__)
   1644 int systemNFreeF(char *command, int line, const char *thisFunc, const char *thisFileName) MUST_CHECK;
   1645 
   1646 // get modification time for path
   1647 time_t getModificationTime(const char *path) MUST_CHECK;
   1648 
   1649 // set modification time for path
   1650 int setModificationTime(const char *path, time_t mtime) MUST_CHECK;
   1651 
   1652 // true when path is readable
   1653 bool isReadable(const char *path) MUST_CHECK;
   1654 
   1655 // true when path is writable
   1656 bool isWritable(const char *path) MUST_CHECK;
   1657 
   1658 // true when path is executable
   1659 bool isExecutable(const char *path) MUST_CHECK;
   1660 
   1661 // compare modification times for path1 and path2
   1662 bool equalModificationTimes(const char *path1, const char *path2) MUST_CHECK;
   1663 
   1664 // get current unix time
   1665 time_t getCurrentUnixTime(void) MUST_CHECK;
   1666 
   1667 // convert date string to unix time
   1668 time_t strToUnixTime(const char *date, const char *format) MUST_CHECK;
   1669 
   1670 // convert unix time to string
   1671 char *timeToS(const time_t t) MUST_CHECK;
   1672 char *bTimeToS(char *dst, const time_t t) MUST_CHECK;
   1673 char *bLTimeToS(char *dst, size_t dstSize, const time_t t) MUST_CHECK;
   1674 
   1675 // convert unix time to Y-m-d H:M:S string
   1676 char *timeToYMDS(const time_t t) MUST_CHECK;
   1677 char *bTimeToYMDS(char *dst, const time_t t) MUST_CHECK;
   1678 char *bLTimeToYMDS(char *dst, size_t dstSize, const time_t t) MUST_CHECK;
   1679 
   1680 // get current date in ctime format
   1681 char *getCurrentDate(void) MUST_CHECK;
   1682 char *bGetCurrentDate(char *dst) MUST_CHECK;
   1683 char *bLGetCurrentDate(char *dst, size_t dstSize) MUST_CHECK;
   1684 
   1685 // get current date in Y-m-d H:M:S format
   1686 char *getCurrentDateYMD(void) MUST_CHECK;
   1687 char *bGetCurrentDateYMD(char *dst) MUST_CHECK;
   1688 char *bLGetCurrentDateYMD(char *dst, size_t dstSize) MUST_CHECK;
   1689 
   1690 // dirname
   1691 char *shDirname(const char *path) MUST_CHECK;
   1692 char *bDirname(char *path) MUST_CHECK;
   1693 char *bLDirname(char *path, size_t pathSize) MUST_CHECK;
   1694 
   1695 // expand home ~/
   1696 char *expandHome(const char *path) MUST_CHECK;
   1697 char *iExpandHome(char **path) MUST_CHECK;
   1698 char *bExpandHome(char *path) MUST_CHECK;
   1699 char *bLExpandHome(char *path, size_t pathSize) MUST_CHECK;
   1700 
   1701 // normalize path
   1702 char *normalizePath(const char *path) MUST_CHECK;
   1703 char *iNormalizePath(char **path) MUST_CHECK;
   1704 char *bNormalizePath(char *path) MUST_CHECK;
   1705 char *bLNormalizePath(char *path, size_t pathSize) MUST_CHECK;
   1706 
   1707 // relative path
   1708 char *relPath(const char *path, const char *start) MUST_CHECK;
   1709 char *iRelPath(char **path, const char *start) MUST_CHECK;
   1710 char *bRelPath(char *dest, const char *path, const char *start) MUST_CHECK;
   1711 char *bLRelPath(char *dest, size_t destSize, char *path, const char *start) MUST_CHECK;
   1712 
   1713 // get home path
   1714 char *getHomePath(void) MUST_CHECK;
   1715 char *bGetHomePath(char *path) MUST_CHECK;
   1716 char *bLGetHomePath(char *path, size_t pathSize) MUST_CHECK;
   1717 const char *getCHomePath(void) MUST_CHECK;
   1718 
   1719 // get current working directory
   1720 char *getCwd(void) MUST_CHECK;
   1721 char *bLGetCwd(char *path, size_t pathSize) MUST_CHECK;
   1722 
   1723 // change directory
   1724 int chDir(const char *path) MUST_CHECK;
   1725 
   1726 // true when path is directory
   1727 bool isDir(const char *path) MUST_CHECK;
   1728 
   1729 // read link to a new string
   1730 char *shReadlink(const char *path) MUST_CHECK;
   1731 
   1732 // read link chain to the end to a new string
   1733 char *endlink(const char *path) MUST_CHECK;
   1734 
   1735 // true when path is symbolic link
   1736 bool isLink(const char *path) MUST_CHECK;
   1737 
   1738 // file and dir exists
   1739 bool fileExists(const char *filePath) MUST_CHECK;
   1740 #define isPath fileExists
   1741 
   1742 // chmod "721"
   1743 bool fileChmod(const char *filePath, mode_t mode) MUST_CHECK;
   1744 
   1745 // file size
   1746 ssize_t fileSize(const char *filePath) MUST_CHECK;
   1747 ssize_t fileSizeFP(FILE *fp) MUST_CHECK;
   1748 
   1749 // read file
   1750 void *readFileToS(const char *filePath) MUST_CHECK;
   1751 void *bReadFileToS(const char *filePath, void *dst) MUST_CHECK;
   1752 void *bLReadFileToS(const char *filePath, void *dst, size_t dstSize) MUST_CHECK;
   1753 ssize_t readFile(const char *filePath, void **buffer) MUST_CHECK;
   1754 ssize_t bReadFile(const char *filePath, void *buffer) MUST_CHECK;
   1755 ssize_t bLReadFile(const char *filePath, void *buffer, size_t dstSize) MUST_CHECK;
   1756 void *readStreamToS(FILE *fp) MUST_CHECK;
   1757 void *bReadStreamToS(FILE *fp, void *dst) MUST_CHECK;
   1758 void *bLReadStreamToS(FILE *fp, void *dst, size_t dstSize) MUST_CHECK;
   1759 // defines without '...ToS'
   1760 #define readFileS     readFileToS
   1761 #define bReadFileS    bReadFileToS
   1762 #define bLReadFileS   bLReadFileToS
   1763 #define readStreamS   readStreamToS
   1764 #define bReadStreamS  bReadStreamToS
   1765 #define bLReadStreamS bLReadStreamToS
   1766 
   1767 // write file
   1768 int writeFileS(const char *filePath, const char *string) MUST_CHECK;
   1769 int writeFile(const char *filePath, void *buffer, size_t len) MUST_CHECK;
   1770 int writeStreamS(FILE *fp, const char *string) MUST_CHECK;
   1771 int writeLStream(FILE *fp, void *buffer, size_t len) MUST_CHECK;
   1772 
   1773 // append string to file
   1774 bool appendFileS(const char *filePath, const char *string) MUST_CHECK;
   1775 bool appendFile(const char *filePath, void *buffer, size_t len) MUST_CHECK;
   1776 
   1777 // walkDir lists files only
   1778 char **walkDir(const char* dirPath) MUST_CHECK;
   1779 
   1780 // walkDirDir lists directories
   1781 char **walkDirDir(const char* dirPath) MUST_CHECK;
   1782 
   1783 // readDir lists files in a directory
   1784 char **readDir(const char *dirPath) MUST_CHECK;
   1785 
   1786 // readDirDir lists directories in a directory
   1787 char **readDirDir(const char *dirPath) MUST_CHECK;
   1788 
   1789 // walkDirAll lists files and directories
   1790 char **walkDirAll(const char* dirPath) MUST_CHECK;
   1791 
   1792 // readDirAll lists files and directories in a directory
   1793 char **readDirAll(const char *dirPath) MUST_CHECK;
   1794 
   1795 // get umask
   1796 mode_t getUmask(void) MUST_CHECK;
   1797 
   1798 // get current permissions for creating directories
   1799 mode_t getCurrentPermissions(void) MUST_CHECK;
   1800 
   1801 // recursive mkdir
   1802 int mkdirParents(const char* path) MUST_CHECK;
   1803 
   1804 // delete files and directories
   1805 int rmAll(const char* path) MUST_CHECK;
   1806 
   1807 // copy files recursively
   1808 int copy(const char* src, const char* dst) MUST_CHECK;
   1809 
   1810 // rename file
   1811 int shRename(const char* src, const char* dst) MUST_CHECK;
   1812 
   1813 // move files recursively
   1814 int shMove(const char* src, const char* dst) MUST_CHECK;
   1815 
   1816 // use /dev/urandom as a source of random numbers
   1817 void setSoftwareRandom(void);
   1818 
   1819 // use cpu random instruction as a source of random numbers
   1820 void setHardwareRandom(void);
   1821 
   1822 // open /dev/urandom in libsheepy
   1823 int randomUrandomOpen(void) MUST_CHECK;
   1824 
   1825 // close /dev/urandom in libsheepy
   1826 void randomUrandomClose(void);
   1827 
   1828 // return random 64 bit unsigned integer
   1829 uint64_t randomWord(void) MUST_CHECK;
   1830 
   1831 // return random 64 bit unsigned integer from the cpu
   1832 uint64_t randomWordFromHW(void) MUST_CHECK;
   1833 
   1834 // return a random value between 0 and range 0<=value<range
   1835 uint64_t randomChoice(uint64_t range) MUST_CHECK;
   1836 
   1837 // generate random string
   1838 char *randomS(uint64_t length) MUST_CHECK;
   1839 char *bRandomS(char *dst, size_t length) MUST_CHECK;
   1840 
   1841 // generate random alpha numerical string
   1842 char *randomAlphaNumS(uint64_t length) MUST_CHECK;
   1843 char *bRandomAlphaNumS(char *dst, size_t dstSize) MUST_CHECK;
   1844 
   1845 // read user input (one line) as a string
   1846 char *readS(void) MUST_CHECK;
   1847 char *bLReadS(char *dst, size_t dstSize) MUST_CHECK;
   1848 
   1849 // read hidden password as a string - like getpass
   1850 char *readPasswordS(void) MUST_CHECK;
   1851 
   1852 // write zero to all bytes in string with memset, for clearing password buffers
   1853 bool zeroS(char *string) MUST_CHECK;
   1854 
   1855 // write zero to all bytes in buffer with memset
   1856 bool zeroBuf(void *buf, size_t len) MUST_CHECK;
   1857 
   1858 // allocate and copy buffer
   1859 void *memdup(const void *buf, size_t size) MUST_CHECK;
   1860 
   1861 // wait until press the enter key
   1862 void readEnter(void);
   1863 
   1864 // TODO writeLine - copy cg_c code
   1865 
   1866 // readLine
   1867 char *readLine(FILE *fp) MUST_CHECK;
   1868 
   1869 // convert char to string by declaring string dst with c in it
   1870 #define charToS(dst, c) \
   1871   ;char dst[2] = {c, 0}
   1872 
   1873 // free many char*
   1874 void freeManySF(char *paramType, ...);
   1875 #define freeManyS(...) freeManySF("", __VA_ARGS__, NULL)
   1876 
   1877 // duplicate string
   1878 char *dupS(const char *string) MUST_CHECK;
   1879 
   1880 // print like printf, the formating can be NULL
   1881 void shPrintfS(const char *fmt, ...);
   1882 
   1883 // stderr printf, the formating can be NULL
   1884 void shEPrintfS(const char *fmt, ...);
   1885 
   1886 // print and free s
   1887 void logNFree(char *s);
   1888 
   1889 // print buf as hexadecimal
   1890 void loghex(const void *buf, size_t len);
   1891 
   1892 // create a string with bytes in buf converted to hex strings: 0xff,
   1893 char *toHexS(const void *buf, size_t len) MUST_CHECK;
   1894 
   1895 // create a string with bytes in buf converted to hex strings separated by separator: 0xffSEP
   1896 char *toHexSepS(const void *buf, size_t len, const char *separator) MUST_CHECK;
   1897 
   1898 // create a string with bytes in buf converted to hex strings separated by separator and with head string in front of earch byte: HEADffSEP
   1899 char *toHexHeadSepS(const void *buf, size_t len, const char *head, const char *separator) MUST_CHECK;
   1900 
   1901 // print new line
   1902 #define put puts("");
   1903 
   1904 // copy src to dst
   1905 char *strCpy(char *restrict dst, const char *restrict src) MUST_CHECK;
   1906 // copy string to buffer given string length: strNCpy(buffer, string, lenS(string));
   1907 // null safe version of strncpy
   1908 char *strNCpy(char *restrict dst, const char *restrict src, size_t srcSize) MUST_CHECK;
   1909 char *strLCpy(char *restrict dst, size_t dstSize, const char *restrict src) MUST_CHECK;
   1910 
   1911 // concatenate src to dst
   1912 char *strCat(char *restrict dst, const char *restrict src) MUST_CHECK;
   1913 char *strNCat(char *restrict dst, const char *restrict src, size_t srcLen) MUST_CHECK;
   1914 char *strLCat(char *restrict dst, size_t dstSize, const char *restrict src) MUST_CHECK;
   1915 char *strLNCat(char *restrict dst, size_t dstSize, const char *restrict src, size_t srcLen) MUST_CHECK;
   1916 
   1917 // cat: f("qwd ", str," werr ", str2)
   1918 char *catSF(const char *paramType, ...) MUST_CHECK;
   1919 #define catS(...) catSF("", __VA_ARGS__, NULL)
   1920 
   1921 // cat and copy result to dst buffer
   1922 char *iCatSF(char *dst, const char *paramType, ...) MUST_CHECK;
   1923 #define iCatS(dst, ...) iCatSF(dst, "", __VA_ARGS__, NULL)
   1924 #define bCatS iCatS
   1925 char *bLCatSF(char *dst, size_t dstSize, const char *paramType, ...) MUST_CHECK;
   1926 #define bLCatS(dst, dstSize, ...) bLCatSF(dst, dstSize, "", __VA_ARGS__, NULL)
   1927 
   1928 // allocate and format string using asprintf
   1929 char *formatS(const char *fmt, ...) MUST_CHECK;
   1930 
   1931 /** format and store in string: bFormatS(string, "Value %d", i); */
   1932 char *bFormatS(char *string, const char *fmt, ...) MUST_CHECK;
   1933 
   1934 /** format and store in string: bLFormatS(string, sizeof(string), "Value %d", i); */
   1935 char *bLFormatS(char *string, size_t stringSize, const char *fmt, ...) MUST_CHECK;
   1936 
   1937 // append strings
   1938 char *appendS(const char *string1, const char *string2) MUST_CHECK;
   1939 char *appendCharS(const char *string1, char c) MUST_CHECK;
   1940 char *appendSChar(char c, const char *string2) MUST_CHECK;
   1941 char *iAppendS(char **string1, const char *string2) MUST_CHECK;
   1942 char *iAppendCharS(char **string1, char c) MUST_CHECK;
   1943 char *iAppendNFreeS(char **string1, char *string2) MUST_CHECK;
   1944 char *iAppendManySF(char **string, const char *paramType, ...) MUST_CHECK;
   1945 #define iAppendManyS(s, s1, ...) iAppendManySF(s, s1, __VA_ARGS__, NULL)
   1946 char *bAppendManySF(char *string, const char *paramType, ...) MUST_CHECK;
   1947 #define bAppendManyS(s, s1, ...) bAppendManySF(s, s1, __VA_ARGS__, NULL)
   1948 char *bLAppendManySF(char *string, size_t stringSize, const char *paramType, ...) MUST_CHECK;
   1949 #define bLAppendManyS(s, sSize, s1, ...) bLAppendManySF(s, sSize, s1, __VA_ARGS__, NULL)
   1950 
   1951 // prepend string
   1952 char *prependS(const char *string1, const char *string2) MUST_CHECK;
   1953 char *prependCharS(const char *string1, char c) MUST_CHECK;
   1954 char *prependSChar(char c, const char *string2) MUST_CHECK;
   1955 char *iPrependS(char **string1, const char *string2) MUST_CHECK;
   1956 char *iPrependCharS(char **string1, char c) MUST_CHECK;
   1957 char *iPrependNFreeS(char **string1, char *string2) MUST_CHECK;
   1958 char *bPrependS(char *string1, const char *string2) MUST_CHECK;
   1959 char *bLPrependS(char *string1, size_t string1Size, const char *string2) MUST_CHECK;
   1960 
   1961 // string replace
   1962 char *replaceS(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
   1963 char *replaceCharSS(const char *s, char olds, const char *news, size_t max) MUST_CHECK;
   1964 char *replaceSCharS(const char *s, const char *olds, char news, size_t max) MUST_CHECK;
   1965 char *replaceCharCharS(const char *s, char olds, char news, size_t max) MUST_CHECK;
   1966 #define replaceS_max(s,olds,news) replaceS(s,olds,news, 0)
   1967 #define replaceSMax replaceS_max
   1968 // TODO add support for all types, create a generic, create ignore case version
   1969 size_t replaceSLen(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
   1970 #define replaceSMaxLen(s,olds,news) replaceSLen(s,olds,news, 0)
   1971 char* iReplaceS(char **s, const char *olds, const char *news, size_t max) MUST_CHECK;
   1972 char* iReplaceCharSS(char **s, char olds, const char *news, size_t max) MUST_CHECK;
   1973 char* iReplaceSCharS(char **s, const char *olds, char news, size_t max) MUST_CHECK;
   1974 char* iReplaceCharCharS(char **s, char olds, char news, size_t max) MUST_CHECK;
   1975 #define iReplaceS_max(s,olds,news) iReplaceS(s,olds,news, 0)
   1976 #define iReplaceSMax iReplaceS_max
   1977 char* bReplaceS(char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
   1978 #define bReplaceS_max(s,olds,news) bReplaceS(s,olds,news, 0)
   1979 #define bReplaceSMax bReplaceS_max
   1980 char* bLReplaceS(char *s, size_t sSize, const char *olds, const char *news, size_t max) MUST_CHECK;
   1981 #define bLReplaceS_max(s,sSize,olds,news) bLReplaceS(s,sSize,olds,news, 0)
   1982 #define bLReplaceSMax bLReplaceS_max
   1983 
   1984 // string replace many olds with news (s, olds1, news1, olds2, news2,...)
   1985 char *replaceManySF(const char *paramType, ...) MUST_CHECK;
   1986 #define replaceManyS(s, ...) replaceManySF(s, __VA_ARGS__, NULL)
   1987 char *iReplaceManySF(char **string, char *paramType, ...) MUST_CHECK;
   1988 #define iReplaceManyS(s, olds, ...) iReplaceManySF(s, olds, __VA_ARGS__, NULL)
   1989 char *bReplaceManySF(char *s, char *paramType, ...) MUST_CHECK;
   1990 #define bReplaceManyS(s, olds, ...) bReplaceManySF(s, olds, __VA_ARGS__, NULL)
   1991 char *bLReplaceManySF(char *s, size_t sSize, char *paramType, ...) MUST_CHECK;
   1992 #define bLReplaceManyS(s, sSize, olds, ...) bLReplaceManySF(s, sSize, olds, __VA_ARGS__, NULL)
   1993 
   1994 // ignore case string replace
   1995 char *icReplaceS(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
   1996 char *icReplaceCharSS(const char *s, char olds, const char *news, size_t max) MUST_CHECK;
   1997 char *icReplaceSCharS(const char *s, const char *olds, char news, size_t max) MUST_CHECK;
   1998 char *icReplaceCharCharS(const char *s, char olds, char news, size_t max) MUST_CHECK;
   1999 #define icReplaceS_max(s,olds,news) icReplaceS(s,olds,news, 0)
   2000 #define icReplaceSMax icReplaceS_max
   2001 char* iicReplaceS(char **s, const char *olds, const char *news, size_t max) MUST_CHECK;
   2002 char* iicReplaceCharSS(char **s, char olds, const char *news, size_t max) MUST_CHECK;
   2003 char* iicReplaceSCharS(char **s, const char *olds, char news, size_t max) MUST_CHECK;
   2004 char* iicReplaceCharCharS(char **s, char olds, char news, size_t max) MUST_CHECK;
   2005 #define iicReplaceS_max(s,olds,news) iicReplaceS(s,olds,news, 0)
   2006 #define iicReplaceSMax iicReplaceS_max
   2007 char* bicReplaceS(char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
   2008 #define bicReplaceS_max(s,olds,news) bicReplaceS(s,olds,news, 0)
   2009 #define bicReplaceSMax bicReplaceS_max
   2010 char* bLicReplaceS(char *s, size_t sSize, const char *olds, const char *news, size_t max) MUST_CHECK;
   2011 #define bLicReplaceS_max(s,sSize,olds,news) bLicReplaceS(s,sSize,olds,news, 0)
   2012 #define bLicReplaceSMax bLicReplaceS_max
   2013 
   2014 // string replace many olds with news (s, olds1, news1, olds2, news2,...)
   2015 char *icReplaceManySF(const char *paramType, ...) MUST_CHECK;
   2016 #define icReplaceManyS(s, ...) icReplaceManySF(s, __VA_ARGS__, NULL)
   2017 char *iicReplaceManySF(char **string, char *paramType, ...) MUST_CHECK;
   2018 #define iicReplaceManyS(s, olds, ...) iicReplaceManySF(s, olds, __VA_ARGS__, NULL)
   2019 char *bicReplaceManySF(char *s, char *paramType, ...) MUST_CHECK;
   2020 #define bicReplaceManyS(s, olds, ...) bicReplaceManySF(s, olds, __VA_ARGS__, NULL)
   2021 char *bLicReplaceManySF(char *s, size_t sSize, char *paramType, ...) MUST_CHECK;
   2022 #define bLicReplaceManyS(s, sSize, olds, ...) bLicReplaceManySF(s, sSize, olds, __VA_ARGS__, NULL)
   2023 
   2024 // string equal (compare content)
   2025 bool eqS(const char *string1, const char *string2) MUST_CHECK;
   2026 #define strEq eqS
   2027 bool eqCharS(char c, const char *string2) MUST_CHECK;
   2028 bool eqSChar(const char *string1, char c) MUST_CHECK;
   2029 
   2030 // string equal at index (compare content)
   2031 bool eqIS(const char *string1, const char *string2, int64_t index) MUST_CHECK;
   2032 #define strIEq eqIS
   2033 bool eqICharS(const char *string1, char c, int64_t index) MUST_CHECK;
   2034 
   2035 // look for string2 at string1 start
   2036 bool startsWithS(const char *string1, const char *string2) MUST_CHECK;
   2037 bool startsWithCharS(const char *string1, char c) MUST_CHECK;
   2038 
   2039 // look for string2 at string1 end
   2040 bool endsWithS(const char *string1, const char *string2) MUST_CHECK;
   2041 bool endsWithCharS(const char *string1, char c) MUST_CHECK;
   2042 
   2043 // count number of (non-overlapping) occurrences of a substring
   2044 ssize_t countS(const char *s, const char *needle) MUST_CHECK;
   2045 ssize_t countCharS(const char *s, char c) MUST_CHECK;
   2046 
   2047 // ignore case string equal (compare content)
   2048 bool icEqS(const char *string1, const char *string2) MUST_CHECK;
   2049 bool icEqCharS(char c, const char *string2) MUST_CHECK;
   2050 bool icEqSChar(const char *string1, char c) MUST_CHECK;
   2051 
   2052 // ignore case string equal at index (compare content)
   2053 bool icEqIS(const char *string1, const char *string2, int64_t index) MUST_CHECK;
   2054 bool icEqICharS(const char *string1, char c, int64_t index) MUST_CHECK;
   2055 
   2056 // ignore case and look for string2 at string1 start
   2057 bool icStartsWithS(const char *string1, const char *string2) MUST_CHECK;
   2058 bool icStartsWithCharS(const char *string1, char c) MUST_CHECK;
   2059 
   2060 // ignore case look for string2 at string1 end
   2061 bool icEndsWithS(const char *string1, const char *string2) MUST_CHECK;
   2062 bool icEndsWithCharS(const char *string1, char c) MUST_CHECK;
   2063 
   2064 // ignore case and count number of (non-overlapping) occurrences of a substring
   2065 ssize_t icCountS(const char *s, const char *needle) MUST_CHECK;
   2066 ssize_t icCountCharS(const char *s, char c) MUST_CHECK;
   2067 
   2068 // has terminal control char (for example colors)
   2069 bool hasCtrlChar(const char *string) MUST_CHECK;
   2070 
   2071 // remove terminal control char from string
   2072 char *stripCtrlS(const char *string) MUST_CHECK;
   2073 char *iStripCtrlS(char **string) MUST_CHECK;
   2074 char *bStripCtrlS(char *string) MUST_CHECK;
   2075 
   2076 // remove ansi colors from string
   2077 char *stripColorsS(const char *string) MUST_CHECK;
   2078 char *iStripColorsS(char **string) MUST_CHECK;
   2079 char *bStripColorsS(char *string) MUST_CHECK;
   2080 
   2081 // escape quotes and backslashes in string
   2082 char* quoteS(const char *s, char delim) MUST_CHECK;
   2083 char* bQuoteS(char *dest, const char *s, char delim) MUST_CHECK;
   2084 char* bLQuoteS(char *dest, size_t destSize, const char *s, char delim) MUST_CHECK;
   2085 size_t quoteLenS(const char *s, char delim) MUST_CHECK;
   2086 // escape string to become a parsable json string
   2087 char* escapeS(const char *s, char delim /*string delimiter ' or "*/) MUST_CHECK;
   2088 char* bEscapeS(char *dest, const char *s, char delim /*string delimiter ' or "*/) MUST_CHECK;
   2089 char* bLEscapeS(char *dest, size_t destSize, const char *s, char delim /*string delimiter ' or "*/) MUST_CHECK;
   2090 size_t escapeLenS(const char *s, char delim /*string delimiter ' or "*/) MUST_CHECK;
   2091 // convert nibble to hexadecimal digit character
   2092 char nibbleToHex(u8 n) MUST_CHECK;
   2093 // escape string to become compilable in a C source code
   2094 char* cEscapeS(const char *S) MUST_CHECK;
   2095 char* bCEscapeS(char *dest, const char *S) MUST_CHECK;
   2096 char* bLCEscapeS(char *dest, size_t destSize, const char *S) MUST_CHECK;
   2097 size_t cEscapeLenS(const char *s) MUST_CHECK;
   2098 
   2099 // true when string is a number (integer or float)
   2100 bool isNumber(const char *string) MUST_CHECK;
   2101 
   2102 // true when string is an integer
   2103 bool isInt(const char *string) MUST_CHECK;
   2104 
   2105 // parseInt
   2106 int64_t parseInt(const char *string) MUST_CHECK;
   2107 int64_t parseIntChar(char c) MUST_CHECK;
   2108 int64_t parseI64(const char *string) MUST_CHECK;
   2109 int64_t parseI64Char(char c) MUST_CHECK;
   2110 
   2111 // parseDouble
   2112 double parseDouble(const char *string) MUST_CHECK;
   2113 double parseDoubleChar(char c) MUST_CHECK;
   2114 
   2115 // parse hexadecimal string: 0xff
   2116 uint64_t parseHex(const char *string) MUST_CHECK;
   2117 // TODO parseHexChar
   2118 
   2119 // convert int to string
   2120 char *intToS(int64_t n) MUST_CHECK;
   2121 char *bIntToS(char *s, int64_t n) MUST_CHECK;
   2122 
   2123 // convert double to string
   2124 char *doubleToS(double n) MUST_CHECK;
   2125 char *bDoubleToS(char *s, double n) MUST_CHECK;
   2126 
   2127 // length
   2128 size_t lenS(const char *string) MUST_CHECK;
   2129 // string buffer size: strlen+1
   2130 size_t sizeS(const char *string) MUST_CHECK;
   2131 
   2132 /**
   2133  * upper case and store the result in c and return the result
   2134  */
   2135 #define toUpper(c) ((c) = toupper(c), c)
   2136 
   2137 // duplicate and upper case
   2138 char *upperS(const char *string) MUST_CHECK;
   2139 char *iUpperS(char **string) MUST_CHECK;
   2140 char *bUpperS(char *string) MUST_CHECK;
   2141 
   2142 /**
   2143  * lower case and store the result in c and return the result
   2144  */
   2145 #define toLower(c) ((c) = tolower(c), c)
   2146 
   2147 // duplicate and lower case
   2148 char *lowerS(const char *string) MUST_CHECK;
   2149 char *iLowerS(char **string) MUST_CHECK;
   2150 char *bLowerS(char *string) MUST_CHECK;
   2151 
   2152 // duplicate and trim
   2153 char *trimS(const char *string) MUST_CHECK;
   2154 char *iTrimS(char **string) MUST_CHECK;
   2155 char *bTrimS(char *string) MUST_CHECK;
   2156 char *lTrimS(const char *string) MUST_CHECK;
   2157 char *iLTrimS(char **string) MUST_CHECK;
   2158 char *bLTrimS(char *string) MUST_CHECK;
   2159 char *rTrimS(const char *string) MUST_CHECK;
   2160 char *iRTrimS(char **string) MUST_CHECK;
   2161 char *bRTrimS(char *string) MUST_CHECK;
   2162 
   2163 // remove successive repetitions of char c
   2164 char *uniqS(const char *string, char c) MUST_CHECK;
   2165 char *iUniqS(char **string, char c) MUST_CHECK;
   2166 char *bUniqS(char *string, char c) MUST_CHECK;
   2167 #define uniqSlash(s) uniqS(s, '/')
   2168 #define iUniqSlash(s) iUniqS(&(s), '/')
   2169 #define bUniqSlash(s) bUniqS(s, '/')
   2170 
   2171 // ignore case and remove successive repetitions of char c
   2172 char *icUniqS(const char *string, char c) MUST_CHECK;
   2173 char *iicUniqS(char **string, char c) MUST_CHECK;
   2174 char *bicUniqS(char *string, char c) MUST_CHECK;
   2175 
   2176 // repeat string count times
   2177 char *repeatS(const char *string, size_t count) MUST_CHECK;
   2178 char *iRepeatS(char **string, size_t count) MUST_CHECK;
   2179 char *bRepeatS(char *dest, const char *string, size_t count) MUST_CHECK;
   2180 char *bLRepeatS(char *dest, size_t destSize, const char *string, size_t count) MUST_CHECK;
   2181 char *repeatCharS(char c, size_t count) MUST_CHECK;
   2182 char *bRepeatCharS(char *dest, char c, size_t count) MUST_CHECK;
   2183 char *bLRepeatCharS(char *dest, size_t destSize, char c, size_t count) MUST_CHECK;
   2184 
   2185 // length of string repeated count times
   2186 ssize_t repeatLenS(const char *string, size_t count) MUST_CHECK;
   2187 
   2188 // ellipsisStart string
   2189 char *ellipsisStartS(const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
   2190 char *iEllipsisStartS(char **string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
   2191 char *bEllipsisStartS(char *dest, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
   2192 char *bLEllipsisStartS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
   2193 char *ellipsisStartCharS(const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
   2194 char *iEllipsisStartCharS(char **string, size_t targetLength, char ellipsisChar) MUST_CHECK;
   2195 char *bEllipsisStartCharS(char *dest, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
   2196 char *bLEllipsisStartCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
   2197 
   2198 // length of string after ellipsis
   2199 ssize_t ellipsisLenS(const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
   2200 
   2201 // ellipsisEnd string
   2202 char *ellipsisEndS(const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
   2203 char *iEllipsisEndS(char **string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
   2204 char *bEllipsisEndS(char *dest, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
   2205 char *bLEllipsisEndS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *ellipsisString) MUST_CHECK;
   2206 char *ellipsisEndCharS(const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
   2207 char *iEllipsisEndCharS(char **string, size_t targetLength, char ellipsisChar) MUST_CHECK;
   2208 char *bEllipsisEndCharS(char *dest, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
   2209 char *bLEllipsisEndCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char ellipsisChar) MUST_CHECK;
   2210 
   2211 // padStart string
   2212 char *padStartS(const char *string, size_t targetLength, const char *padString) MUST_CHECK;
   2213 char *iPadStartS(char **string, size_t targetLength, const char *padString) MUST_CHECK;
   2214 char *bPadStartS(char *dest, const char *string, size_t targetLength, const char *padString) MUST_CHECK;
   2215 char *bLPadStartS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *padString) MUST_CHECK;
   2216 char *padStartCharS(const char *string, size_t targetLength, char padChar) MUST_CHECK;
   2217 char *iPadStartCharS(char **string, size_t targetLength, char padChar) MUST_CHECK;
   2218 char *bPadStartCharS(char *dest, const char *string, size_t targetLength, char padChar) MUST_CHECK;
   2219 char *bLPadStartCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char padChar) MUST_CHECK;
   2220 
   2221 // length of string after padStart
   2222 ssize_t padStartLenS(const char *string, size_t targetLength, const char *padString) MUST_CHECK;
   2223 
   2224 // padEnd string
   2225 char *padEndS(const char *string, size_t targetLength, const char *padString) MUST_CHECK;
   2226 char *iPadEndS(char **string, size_t targetLength, const char *padString) MUST_CHECK;
   2227 char *bPadEndS(char *dest, const char *string, size_t targetLength, const char *padString) MUST_CHECK;
   2228 char *bLPadEndS(char *dest, size_t destSize, const char *string, size_t targetLength, const char *padString) MUST_CHECK;
   2229 char *padEndCharS(const char *string, size_t targetLength, char padChar) MUST_CHECK;
   2230 char *iPadEndCharS(char **string, size_t targetLength, char padChar) MUST_CHECK;
   2231 char *bPadEndCharS(char *dest, const char *string, size_t targetLength, char padChar) MUST_CHECK;
   2232 char *bLPadEndCharS(char *dest, size_t destSize, const char *string, size_t targetLength, char padChar) MUST_CHECK;
   2233 
   2234 // length of string after padEnd
   2235 ssize_t padEndLenS(const char *string, size_t targetLength, const char *padString) MUST_CHECK;
   2236 
   2237 // get char at python index
   2238 char getS(const char *string, int64_t index) MUST_CHECK;
   2239 
   2240 // set char at python index
   2241 char *setS(char *string, int64_t index, char c) MUST_CHECK;
   2242 
   2243 // swap characters in a string
   2244 char *swapS(char *string, int64_t index1, int64_t index2) MUST_CHECK;
   2245 char *iSwapS(char **string, int64_t index1, int64_t index2) MUST_CHECK;
   2246 char *bSwapS(char *string, int64_t index1, int64_t index2) MUST_CHECK;
   2247 char *bLSwapS(char *string, size_t size, int64_t index1, int64_t index2) MUST_CHECK;
   2248 
   2249 // slice string
   2250 // function to slice parts of a string [1:10] - python style indexes 0..len-1 -1..-len+1
   2251 char *sliceS(const char *string, int64_t start, int64_t end) MUST_CHECK;
   2252 char *iSliceS(char **string, int64_t start, int64_t end) MUST_CHECK;
   2253 char *bSliceS(char *string, int64_t start, int64_t end) MUST_CHECK;
   2254 char *bLSliceS(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK;
   2255 
   2256 // crop string (slice+del)
   2257 char *cropS(char *string, int64_t start, int64_t end) MUST_CHECK;
   2258 char *iCropS(char **string, int64_t start, int64_t end) MUST_CHECK;
   2259 char cropElemS(char *string, int64_t index) MUST_CHECK;
   2260 char iCropElemS(char **string, int64_t index) MUST_CHECK;
   2261 
   2262 // insert string in string
   2263 char *insertS(const char *string, int64_t index, const char *toInsert) MUST_CHECK;
   2264 char *insertNFreeS(const char *string, int64_t index, char *toInsert) MUST_CHECK;
   2265 char *iInsertS(char **string, int64_t index, const char *toInsert) MUST_CHECK;
   2266 char *iInsertNFreeS(char **string, int64_t index, char *toInsert) MUST_CHECK;
   2267 char *bInsertS(char *string, int64_t index, const char *toInsert) MUST_CHECK;
   2268 char *bLInsertS(char *string, size_t stringSize, int64_t index, const char *toInsert) MUST_CHECK;
   2269 
   2270 // inject a char in string
   2271 char *injectS(const char *string, int64_t index, char toInject) MUST_CHECK;
   2272 char *iInjectS(char **string, int64_t index, char toInject) MUST_CHECK;
   2273 char *bInjectS(char *string, int64_t index, char toInject) MUST_CHECK;
   2274 char *bLInjectS(char *string, size_t stringSize, int64_t index, char toInject) MUST_CHECK;
   2275 
   2276 // del string
   2277 // function to delete parts of a string [1:10] - python style indexes 0..len-1 -1..-len+1
   2278 char *delS(const char *string, int64_t start, int64_t end) MUST_CHECK;
   2279 char *iDelS(char **string, int64_t start, int64_t end) MUST_CHECK;
   2280 char *bDelS(char *string, int64_t start, int64_t end) MUST_CHECK;
   2281 char *bLDelS(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK;
   2282 
   2283 // del a character in string
   2284 char *delElemS(const char *string, int64_t index) MUST_CHECK;
   2285 char *iDelElemS(char **string, int64_t index) MUST_CHECK;
   2286 char *bDelElemS(char *string, int64_t index) MUST_CHECK;
   2287 char *bLDelElemS(char *string, size_t stringSize, int64_t index) MUST_CHECK;
   2288 
   2289 // find substring
   2290 char *findS(const char *string, const char *needle) MUST_CHECK;
   2291 char *findCharS(const char *string, char c) MUST_CHECK;
   2292 ssize_t indexOfS(const char *string, const char *needle) MUST_CHECK;
   2293 ssize_t indexOfCharS(const char *string, char c) MUST_CHECK;
   2294 
   2295 // true when needle is found
   2296 bool hasS(const char *string, const char *needle) MUST_CHECK;
   2297 bool hasCharS(const char *string, char c) MUST_CHECK;
   2298 
   2299 // ignore case find substring
   2300 char *icFindS(const char *string, const char *needle) MUST_CHECK;
   2301 char *icFindCharS(const char *string, char c) MUST_CHECK;
   2302 ssize_t icIndexOfS(const char *string, const char *needle) MUST_CHECK;
   2303 ssize_t icIndexOfCharS(const char *string, char c) MUST_CHECK;
   2304 
   2305 // ignore case, true when needle is found
   2306 bool icHasS(const char *string, const char *needle) MUST_CHECK;
   2307 bool icHasCharS(const char *string, char c) MUST_CHECK;
   2308 
   2309 // parse s string with delim - work like strtok_r from stdlib
   2310 char *tokS(char *s, const char *delim, char **saveptr) MUST_CHECK;
   2311 
   2312 // ignore case and parse s string with delim - work like strtok_r from stdlib
   2313 char *icTokS(char *s, const char *delim, char **saveptr) MUST_CHECK;
   2314 
   2315 //
   2316 // UTF8 string functions
   2317 //
   2318 
   2319 // rune is a 32 bit unicode integer
   2320 typedef int rune;
   2321 
   2322 // character length of UTF-8 encoded string
   2323 size_t lenUTF8(const char *s) MUST_CHECK;
   2324 size_t bLLenUTF8(const char *s, size_t maxSize) MUST_CHECK;
   2325 
   2326 // is string valid UTF-8 encoded string
   2327 bool isUTF8(const char * string) MUST_CHECK;
   2328 bool bLIsUTF8(const char * string, size_t stringSize) MUST_CHECK;
   2329 
   2330 // is string a valid UTF-8 code point
   2331 bool isCodeUTF8(const char *code) MUST_CHECK;
   2332 
   2333 extern const uint8_t codeSzUTF8[256];
   2334 
   2335 /** size in bytes of UTF-8 code point  */
   2336 #define codeSizeUTF8(utf8) codeSzUTF8[*(const uint8_t *)(utf8)]
   2337 
   2338 /** move pointer to next UTF-8 code point, no checks are done, the utf8 pointer parameter is unchanged */
   2339 #define nextCodeUTF8(utf8) ((utf8) + codeSizeUTF8(utf8))
   2340 
   2341 /** change the utf8 pointer parameter to next UTF-8 code point, like char *s; s++; */
   2342 #define nxtCodeUTF8(utf8) EVA(utf8, nextCodeUTF8(utf8))
   2343 #define nxCodeUTF8(utf8) (utf8 = nextCodeUTF8(utf8))
   2344 
   2345 // next code point, works only when utf8 points to a valid code point
   2346 const char *nextUTF8(const char *utf8) MUST_CHECK;
   2347 const char *bLNextUTF8(const char *string, size_t utf8Size, const char *utf8) MUST_CHECK;
   2348 
   2349 // find next code point even when utf8 points inside a code point
   2350 const char *findNextUTF8(const char *string, size_t utf8Size, const char *utf8) MUST_CHECK;
   2351 
   2352 // previous code point, undefined behavior when utf8 points to the start of the string
   2353 const char *prevUTF8(const char *utf8) MUST_CHECK;
   2354 
   2355 // previous code point
   2356 const char *bPrevUTF8(const char *string, const char *utf8) MUST_CHECK;
   2357 
   2358 // character index to pointer
   2359 const char *idx2PtrUTF8(const char *utf8, int64_t index) MUST_CHECK;
   2360 const char *bLIdx2PtrUTF8(const char *utf8, size_t utf8Size, int64_t index) MUST_CHECK;
   2361 
   2362 // pointer to character index
   2363 int64_t ptr2IdxUTF8(const char *utf8, const char *pos) MUST_CHECK;
   2364 int64_t bPtr2IdxUTF8(const char *start, const char *utf8, const char *pos) MUST_CHECK;
   2365 int64_t bLPtr2IdxUTF8(const char *utf8, size_t utf8Size, const char *pos) MUST_CHECK;
   2366 int64_t bLPtr2NegIdxUTF8(const char *utf8, size_t utf8Size, const char *pos) MUST_CHECK;
   2367 
   2368 // make new valid UTF-8 encoded string
   2369 char *makeValidUTF8(const char *utf8) MUST_CHECK;
   2370 // make utf8 a valid UTF-8 encoded string
   2371 char *bMakeValidUTF8(char *utf8) MUST_CHECK;
   2372 char *nMakeValidUTF8(const char *utf8, size_t utf8Len) MUST_CHECK;
   2373 char *bNMakeValidUTF8(char *dst, const char *utf8, size_t utf8Len) MUST_CHECK;
   2374 char *bLMakeValidUTF8(char *dst, size_t dstSize, const char *utf8) MUST_CHECK;
   2375 char *bLNMakeValidUTF8(char *dst, size_t dstSize, const char *utf8, size_t utf8Len) MUST_CHECK;
   2376 
   2377 // strncpy where srcLen is number of characters
   2378 char *strNCpyUTF8(char *dst, const char *src, size_t srcLen) MUST_CHECK;
   2379 
   2380 // strLCpy for UTF-8 encoded strings
   2381 char *strLCpyUTF8(char *dst, size_t dstSize, const char *src) MUST_CHECK;
   2382 
   2383 // strncat where srcLen is number of characters
   2384 char *strNCatUTF8(char *dst, const char *src, size_t srcLen) MUST_CHECK;
   2385 
   2386 // strLCat for UTF-8 encoded strings
   2387 char *strLCatUTF8(char *dst, size_t dstSize, const char *src) MUST_CHECK;
   2388 
   2389 // strLNCat for UTF-8 encoded strings
   2390 char *strLNCatUTF8(char *dst, size_t dstSize, const char *src, size_t srcLen) MUST_CHECK;
   2391 
   2392 // TODO
   2393 char* icReplaceUTF8(const char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
   2394 // TODO
   2395 char *icReplaceCharSUTF8(const char *s, char olds, const char *news, size_t max) MUST_CHECK;
   2396 // TODO
   2397 char *icReplaceSCharUTF8(const char *s, const char *olds, char news, size_t max) MUST_CHECK;
   2398 // TODO
   2399 char* iicReplaceUTF8(char **s, const char *olds, const char *news, size_t max) MUST_CHECK;
   2400 // TODO
   2401 char *iicReplaceCharSUTF8(char **s, char olds, const char *news, size_t max) MUST_CHECK;
   2402 // TODO
   2403 char *iicReplaceSCharUTF8(char **s, const char *olds, char news, size_t max) MUST_CHECK;
   2404 // TODO
   2405 char* bicReplaceUTF8(char *s, const char *olds, const char *news, size_t max) MUST_CHECK;
   2406 // TODO
   2407 char* bLicReplaceUTF8(char *s, size_t sSize, const char *olds, const char *news, size_t max) MUST_CHECK;
   2408 // TODO
   2409 char *icReplaceManyUTF8F(const char *paramType, ...) MUST_CHECK;
   2410 // TODO
   2411 char *iicReplaceManyUTF8F(char **s, char *paramType, ...) MUST_CHECK;
   2412 // TODO
   2413 char *bicReplaceManyUTF8F(char *s, char *paramType, ...) MUST_CHECK;
   2414 // TODO
   2415 char *bLicReplaceManyUTF8F(char *s, size_t sSize, char *paramType, ...) MUST_CHECK;
   2416 
   2417 // UTF8 encoded string Index Equal
   2418 bool eqIUTF8(const char *string1, const char *string2, int64_t index) MUST_CHECK;
   2419 
   2420 // UTF8 encoded string Index Equal
   2421 bool eqICharUTF8(const char *string1, char c, int64_t index) MUST_CHECK;
   2422 
   2423 // ignore case UTF8 encoded string Equal
   2424 bool icEqUTF8(const char *string1, const char *string2) MUST_CHECK;
   2425 bool icEqCharUTF8(char c, const char *string2) MUST_CHECK;
   2426 bool icEqUTF8Char(const char *string1, char c) MUST_CHECK;
   2427 
   2428 // TODO
   2429 bool icEqIUTF8(const char *string1, const char *string2, int64_t index) MUST_CHECK;
   2430 // TODO
   2431 bool icEqICharUTF8(const char *string1, char c, int64_t index) MUST_CHECK;
   2432 
   2433 // starts with for UTF-8 encoded string
   2434 bool icStartsWithUTF8(const char *string1, const char *string2) MUST_CHECK;
   2435 
   2436 // ends with for UTF-8 encoded string
   2437 bool icEndsWithUTF8(const char *string1, const char *string2) MUST_CHECK;
   2438 
   2439 // ignore case count UTF8 encoded String
   2440 ssize_t icCountUTF8(const char *s, const char *needle) MUST_CHECK;
   2441 
   2442 // UTF-8 code point to rune
   2443 rune code2RuneUTF8(const char *code) MUST_CHECK;
   2444 rune code2RuneLUTF8(const char *code, uint8_t *n) MUST_CHECK;
   2445 
   2446 // rune to UTF-8 code point
   2447 size_t bRune2CodeUTF8(char *dst, rune c) MUST_CHECK;
   2448 
   2449 // rune length as UTF-8 code point
   2450 uint8_t runeLenUTF8(rune r) MUST_CHECK;
   2451 
   2452 // rune toupper UTF8
   2453 rune toupperUTF8(rune c) MUST_CHECK;
   2454 
   2455 // upper case UTF-8 encoded string
   2456 char *upperUTF8(const char *string) MUST_CHECK;
   2457 char *iUpperUTF8(char **string) MUST_CHECK;
   2458 // TODO
   2459 char *bUpperUTF8(char *string) MUST_CHECK;
   2460 
   2461 // rune tolower UTF8
   2462 rune tolowerUTF8(rune c) MUST_CHECK;
   2463 
   2464 // lower case UTF-8 String
   2465 char *lowerUTF8(const char *string) MUST_CHECK;
   2466 char *iLowerUTF8(char **string) MUST_CHECK;
   2467 // TODO
   2468 char *bLowerUTF8(char *string) MUST_CHECK;
   2469 
   2470 // transform UTF-8 string to make it comparable regardless of case
   2471 char *casefoldUTF8(const char *utf8) MUST_CHECK;
   2472 
   2473 // uniquify code point in UTF-8 String
   2474 char *uniqUTF8(const char *string, const char *code) MUST_CHECK;
   2475 char *iUniqUTF8(char **string, const char *code) MUST_CHECK;
   2476 char *bUniqUTF8(char *string, const char *code) MUST_CHECK;
   2477 // TODO
   2478 char *icUniqUTF8(const char *string, const char *code) MUST_CHECK;
   2479 // TODO
   2480 char *iicUniqUTF8(char **string, const char *code) MUST_CHECK;
   2481 // TODO
   2482 char *bicUniqUTF8(char *string, char c) MUST_CHECK;
   2483 
   2484 // get rune in UTF8 encoded string
   2485 rune getUTF8(const char *string, int64_t index) MUST_CHECK;
   2486 
   2487 // TODO
   2488 char *setUTF8(char *string, int64_t index, rune c) MUST_CHECK;
   2489 
   2490 // slice UTF8 encoded String
   2491 char *sliceUTF8(const char *string, int64_t start, int64_t end) MUST_CHECK;
   2492 char *iSliceUTF8(char **string, int64_t start, int64_t end) MUST_CHECK;
   2493 char *bSliceUTF8(char *string, int64_t start, int64_t end) MUST_CHECK;
   2494 char *bLSliceUTF8(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK;
   2495 
   2496 // insert string in UTF8 encoded string at index
   2497 char *insertUTF8(const char *string, int64_t index, const char *toInsert) MUST_CHECK;
   2498 char *insertNFreeUTF8(const char *string, int64_t index, char *toInsert) MUST_CHECK;
   2499 char *iInsertUTF8(char **string, int64_t index, const char *toInsert) MUST_CHECK;
   2500 char *iInsertNFreeUTF8(char **string, int64_t index, char *toInsert) MUST_CHECK;
   2501 char *bInsertUTF8(char *string, int64_t index, const char *toInsert) MUST_CHECK;
   2502 char *bLInsertUTF8(char *string, size_t stringSize, int64_t index, const char *toInsert) MUST_CHECK;
   2503 
   2504 // delete UTF8 encoded string
   2505 char *delUTF8(const char *string, int64_t start, int64_t end) MUST_CHECK;
   2506 char *iDelUTF8(char **string, int64_t start, int64_t end) MUST_CHECK;
   2507 char *bDelUTF8(char *string, int64_t start, int64_t end) MUST_CHECK;
   2508 char *bLDelUTF8(char *string, size_t stringSize, int64_t start, int64_t end) MUST_CHECK;
   2509 
   2510 // indexOf UTF8 encoded String
   2511 ssize_t indexOfUTF8(const char *string, const char *needle) MUST_CHECK;
   2512 // TODO
   2513 ssize_t icIndexOfUTF8(const char *string, const char *needle) MUST_CHECK;
   2514 
   2515 // ignore case has UTF8 encoded String
   2516 bool icHasUTF8(const char *string, const char *needle) MUST_CHECK;
   2517 
   2518 // TODO
   2519 char *icTokUTF8(const char *s, const char *delim, char **saveptr) MUST_CHECK;
   2520 
   2521 // TODO
   2522 char **icExtractUTF8(const char *string, const char* delim1, const char* delim2) MUST_CHECK;
   2523 char **icExtractCharSUTF8(const char *string, char delim1, const char* delim2) MUST_CHECK;
   2524 char **icExtractSCharUTF8(const char *string, const char* delim1, char delim2) MUST_CHECK;
   2525 
   2526 // ignore case list Sort UTF8 encoded String
   2527 char **icListSortUTF8(char **list) MUST_CHECK;
   2528 char **iicListSortUTF8(char ***list) MUST_CHECK;
   2529 
   2530 // ignore case list Equal UTF8 encoded String
   2531 bool icListEqUTF8(char **list1, char **list2) MUST_CHECK;
   2532 
   2533 // ignore case and return true when list has UTF8 encoded string
   2534 bool icListHasUTF8(char **list, const char *string) MUST_CHECK;
   2535 
   2536 // ignore case and return index of UTF8 encoded string in list
   2537 ssize_t icListIndexOfUTF8(char **list, const char *string) MUST_CHECK;
   2538 
   2539 // ignore case list binary search UTF8 encoded string
   2540 ssize_t icListBinarySearchUTF8(char **list, const char *string) MUST_CHECK;
   2541 
   2542 // ignore case and uniquify UTF8 encoded elements of list
   2543 char **icListUniqUTF8(char **list) MUST_CHECK;
   2544 char **iicListUniqUTF8(char ***list) MUST_CHECK;
   2545 
   2546 //
   2547 // End UTF8 string functions
   2548 //
   2549 
   2550 
   2551 // create empty string
   2552 #define emptyS(string) \
   2553   string = strdup("");
   2554 char *emptySF(void) MUST_CHECK;
   2555 char *iEmptySF(char **string) MUST_CHECK;
   2556 // string buffer empty - set 0 at index 0
   2557 #define bEmptyS(string) \
   2558   (string)[0] = 0
   2559 
   2560 // is empty string
   2561 bool isEmptyS(const char *string) MUST_CHECK;
   2562 
   2563 /**
   2564  * orS - if string is empty, the value is alternative
   2565  */
   2566 #define orS(string, alternative) \
   2567   !isEmptyS(string) ? (string) : (alternative)
   2568 
   2569 // true when string is empty or white spaces
   2570 bool isBlankS(const char *string) MUST_CHECK;
   2571 
   2572 /**
   2573  * blankS - if string is blank(white spaces) or empty, the value is alternative
   2574  */
   2575 #define orBlankS(string, alternative) \
   2576   !isBlankS(string) ? (string) : (alternative)
   2577 
   2578 /**
   2579  * nS - null String - replace null string with "" string (empty string)
   2580  */
   2581 #define nS(string) \
   2582   (string) ? (string) : ""
   2583 
   2584 /**
   2585  * nAS - null Alternative String - replace null string with alternative string
   2586  */
   2587 #define nAS(string, alternative) \
   2588   (string) ? (string) : (alternative)
   2589 
   2590 
   2591 // convert python index (int, positive and negative) to always positive index (uint), this function is more generic than listIntIndexS
   2592 ssize_t intIndex(int64_t index, int64_t length);
   2593 
   2594 // create empty list
   2595 #define listEmptyS(list) \
   2596   do {\
   2597     list = malloc(1 * sizeof(char *)); \
   2598     if (list) list[0] = NULL; \
   2599   } while(0);
   2600 
   2601 char **listEmptySF(void) MUST_CHECK;
   2602 char **iListEmptySF(char ***list) MUST_CHECK;
   2603 
   2604 // false when there are elements in the list
   2605 bool listIsEmptyS(char **list) MUST_CHECK;
   2606 
   2607 // false when there are non blank elements in the list
   2608 bool listIsBlankS(char **list) MUST_CHECK;
   2609 
   2610 // String Lists
   2611 // createList(...)
   2612 char **listCreateSF(const char *paramType, ...) MUST_CHECK;
   2613 #define listCreateS(...) listCreateSF("", __VA_ARGS__, NULL)
   2614 
   2615 // copy array to new list
   2616 char **listFromArrayS(char **array, size_t size) MUST_CHECK;
   2617 char **listFromCArrayS(const char **array, size_t size) MUST_CHECK;
   2618 
   2619 // push and pop (append) str
   2620 // modifies the list
   2621 char **listPushS(char ***list, const char *s) MUST_CHECK;
   2622 char **listPushCharS(char ***list, char c) MUST_CHECK;
   2623 char **iListPushS(char ***list, char *s) MUST_CHECK;
   2624 
   2625 // copy last string and free it in the list
   2626 char *listPopS(char ***list) MUST_CHECK;
   2627 
   2628 // prepend and dequeue (append) str
   2629 // modifies the list
   2630 char **listPrependS(char ***list, const char *s) MUST_CHECK;
   2631 char **listPrependCharS(char ***list, char c) MUST_CHECK;
   2632 char **iListPrependS(char ***list, char *s) MUST_CHECK;
   2633 
   2634 // copy fist string and free it in the list
   2635 char *listDequeueS(char ***list) MUST_CHECK;
   2636 
   2637 // freeList
   2638 void listFreeS(char **list);
   2639 
   2640 // free many char**
   2641 void listFreeManySF(char **paramType, ...);
   2642 #define listFreeManyS(...) listFreeManySF(NULL, __VA_ARGS__, NULL)
   2643 
   2644 // length
   2645 size_t listLengthS(char **list) MUST_CHECK;
   2646 size_t listLengthCS(const char **list) MUST_CHECK;
   2647 
   2648 // list length as a single string
   2649 ssize_t listStrLengthS(char **list) MUST_CHECK;
   2650 
   2651 // convert python index (int) to always positive index (uint)
   2652 ssize_t listIntIndexS(char **list, int64_t index) MUST_CHECK;
   2653 
   2654 // pointer to the char* at python index
   2655 char **listAddrS(char **list, int64_t index) MUST_CHECK;
   2656 
   2657 // list get - get a string at python index
   2658 char *listGetS(char **list, int64_t index) MUST_CHECK;
   2659 char *iListGetS(char **list, int64_t index) MUST_CHECK;
   2660 char *listGetCS(const char **list, int64_t index) MUST_CHECK;
   2661 const char *iListGetCS(const char **list, int64_t index) MUST_CHECK;
   2662 
   2663 // list set - replace a string at python index
   2664 char **listSetS(char **list, int64_t index, const char *s) MUST_CHECK;
   2665 char **listSetCharS(char **list, int64_t index, char c) MUST_CHECK;
   2666 char **iListSetS(char **list, int64_t index, char *s) MUST_CHECK;
   2667 
   2668 // swap elements in a list
   2669 char **listSwapS(char **list, int64_t index1, int64_t index2) MUST_CHECK;
   2670 char **iListSwapS(char **list, int64_t index1, int64_t index2) MUST_CHECK;
   2671 
   2672 // split
   2673 char **split(const char *string, const char* delim) MUST_CHECK;
   2674 char **splitS(const char *string, const char* delim) MUST_CHECK;
   2675 char **splitChar(const char *string, char delim) MUST_CHECK;
   2676 
   2677 // ignore case split
   2678 char **icSplit(const char *string, const char* delim) MUST_CHECK;
   2679 char **icSplitS(const char *string, const char* delim) MUST_CHECK;
   2680 char **icSplitChar(const char *string, char delim) MUST_CHECK;
   2681 
   2682 // list length after joined with delimiter
   2683 ssize_t joinLength(char **list, const char* delim) MUST_CHECK;
   2684 
   2685 // join
   2686 char *join(char **list, const char* delim) MUST_CHECK;
   2687 char *joinS(char **list, const char* delim) MUST_CHECK;
   2688 char *joinCS(const char **list, const char* delim) MUST_CHECK;
   2689 char *joinChar(char **list, char delim) MUST_CHECK;
   2690 char *bJoin(char *string, char **list, const char* delim) MUST_CHECK;
   2691 char *bJoinChar(char *string, char **list, char delim) MUST_CHECK;
   2692 char *bLJoin(char *string, size_t stringSize, char **list, const char* delim) MUST_CHECK;
   2693 char *bLJoinChar(char *string, size_t stringSize, char **list, char delim) MUST_CHECK;
   2694 
   2695 // extract string
   2696 char **extractS(const char *string, const char* delim1, const char* delim2) MUST_CHECK;
   2697 char **extractCharSS(const char *string, char delim1, const char* delim2) MUST_CHECK;
   2698 char **extractSCharS(const char *string, const char* delim1, char delim2) MUST_CHECK;
   2699 char **extractCharCharS(const char *string, char delim1, char delim2) MUST_CHECK;
   2700 
   2701 // ignore case extract string
   2702 char **icExtractS(const char *string, const char* delim1, const char* delim2) MUST_CHECK;
   2703 char **icExtractCharSS(const char *string, char delim1, const char* delim2) MUST_CHECK;
   2704 char **icExtractSCharS(const char *string, const char* delim1, char delim2) MUST_CHECK;
   2705 char **icExtractCharCharS(const char *string, char delim1, char delim2) MUST_CHECK;
   2706 
   2707 // duplicate list
   2708 char **listDupS(char **list) MUST_CHECK;
   2709 char **listDupCS(const char **list) MUST_CHECK;
   2710 char **iListDupS(char **list) MUST_CHECK;
   2711 
   2712 // duplicate and reverse list
   2713 char **listReverseS(char **list) MUST_CHECK;
   2714 char **iListReverseS(char ***list) MUST_CHECK;
   2715 
   2716 // listCatS: f(l1, l2, l3)
   2717 char **listCatSF(char **paramType, ...) MUST_CHECK;
   2718 #define listCatS(...) listCatSF(NULL, __VA_ARGS__, NULL)
   2719 
   2720 // append lists
   2721 char **listAppendS(char ***list1, char **list2) MUST_CHECK;
   2722 char **iListAppendS(char ***list1, char **list2) MUST_CHECK;
   2723 char **iListAppendNSmashS(char ***list1, char **list2) MUST_CHECK;
   2724 
   2725 // prepend list at the start and shift existing elements
   2726 char **listShiftS(char ***list1, char **list2) MUST_CHECK;
   2727 char **iListShiftS(char ***list1, char **list2) MUST_CHECK;
   2728 char **iListShiftNSmashS(char ***list1, char **list2) MUST_CHECK;
   2729 
   2730 // add lists
   2731 char **listAddS(char **list1, char **list2);
   2732 char **listAddCS(char **list1, const char **list2);
   2733 
   2734 // slice - python style indexes 0..len-1 -1..-len+1
   2735 char **listSliceS(char **list, int64_t start, int64_t end) MUST_CHECK;
   2736 char **iListCopyS(char **list, int64_t start, int64_t end) MUST_CHECK;
   2737 char **iListSliceS(char ***list, int64_t start, int64_t end) MUST_CHECK;
   2738 
   2739 // crop list (slice+del)
   2740 char **listCropS(char **list, int64_t start, int64_t end) MUST_CHECK;
   2741 char **iListCropS(char ***list, int64_t start, int64_t end) MUST_CHECK;
   2742 char *listCropElemS(char **list, int64_t index) MUST_CHECK;
   2743 char *iListCropElemS(char ***list, int64_t index) MUST_CHECK;
   2744 
   2745 // insert list in list
   2746 char **listInsertS(char **list, int64_t index, char **toInsert) MUST_CHECK;
   2747 char **iListInsertS(char ***list, int64_t index, char **toInsert) MUST_CHECK;
   2748 char **iListInsertNFreeS(char ***list, int64_t index, char **toInsert) MUST_CHECK;
   2749 
   2750 // inject string in list
   2751 char **listInjectS(char **list, int64_t index, char *toInject) MUST_CHECK;
   2752 char **listInjectCharS(char **list, int64_t index, char toInject) MUST_CHECK;
   2753 char **iListInjectS(char ***list, int64_t index, char *toInject) MUST_CHECK;
   2754 char **iListInjectCharS(char ***list, int64_t index, char toInject) MUST_CHECK;
   2755 
   2756 // del - python style indexes 0..len-1 -1..-len+1
   2757 char **listDelS(char **list, int64_t start, int64_t end) MUST_CHECK;
   2758 char **iListDelS(char ***list, int64_t start, int64_t end) MUST_CHECK;
   2759 char **iListRemoveS(char ***list, int64_t start, int64_t end);
   2760 
   2761 // del element in list
   2762 char **listDelElemS(char **list, int64_t index) MUST_CHECK;
   2763 char **iListDelElemS(char ***list, int64_t index) MUST_CHECK;
   2764 char **iListRemoveElemS(char ***list, int64_t index) MUST_CHECK;
   2765 
   2766 // print list
   2767 int listPrintS(char **list) MUST_CHECK;
   2768 int listPrintCS(const char **list) MUST_CHECK;
   2769 
   2770 /**
   2771  * forever loop
   2772  */
   2773 #define forever while(1)
   2774 
   2775 /**
   2776  * range loop
   2777  * ;size_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2778  * on older compilers
   2779  */
   2780 #define range(index, maxCount) \
   2781   ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
   2782   for (size_t index = 0 ; index < UNIQVAR(maxCnt) ; index++)
   2783 
   2784 /**
   2785  * infinity loop
   2786  * increase the index infinitly
   2787  */
   2788 #define rangeInf(index) \
   2789   for (size_t index = 0 ;; index++)
   2790 
   2791 /**
   2792  * range down loop, index is ssize_t
   2793  */
   2794 #define rangeDown(index, maxCount) \
   2795   for (ssize_t index = (maxCount)-1 ; index >= 0 ; index--)
   2796 
   2797 /**
   2798  * range down loop to to index, index is ssize_t
   2799  * ;ssize_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2800  * on older compilers
   2801  */
   2802 #define rangeDownTo(index, maxCount, to) \
   2803   ;ssize_t UNIQVAR(_to) = to;\
   2804   for (ssize_t index = (maxCount)-1 ; index >= UNIQVAR(_to) ; index--)
   2805 
   2806 /**
   2807  * range loop starting at value from
   2808  * ;size_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2809  * on older compilers
   2810  */
   2811 #define rangeFrom(index, from, maxCount) \
   2812   ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
   2813   for (size_t index = from ; index < UNIQVAR(maxCnt) ; index++)
   2814 
   2815 /**
   2816  * loop on the elements of C static array of any type
   2817  *
   2818  * Example:
   2819  * u32 array[20];
   2820  * arange(i, array) {}
   2821  */
   2822 #define arange(index, array) range(index, ARRAY_SIZE(array))
   2823 
   2824 /**
   2825  * loop on the elements of C static array of any type from highest index down to 0
   2826  *
   2827  * Example:
   2828  * u32 array[20];
   2829  * arangeDown(i, array) {}
   2830  */
   2831 #define arangeDown(index, array) rangeDown(index, ARRAY_SIZE(array))
   2832 
   2833 /**
   2834  * loop on the elements of C static array of any type from highest index down to index 'to'
   2835  *
   2836  * Example:
   2837  * u32 array[20];
   2838  * arangeDownTo(i, array, 5) {}
   2839  */
   2840 #define arangeDownTo(index, array, to) rangeDownTo(index, ARRAY_SIZE(array), to)
   2841 
   2842 /**
   2843  * loop on the elements of C static array of any type starting at index 'from'
   2844  *
   2845  * Example:
   2846  * u32 array[20];
   2847  * arange(i, 10, array) {}
   2848  */
   2849 #define arangeFrom(index, from, array) rangeFrom(index, from, ARRAY_SIZE(array))
   2850 
   2851 /**
   2852  * range from value from to maxCount-1 then from 0 to from-1
   2853  *
   2854  * Example:
   2855  * circular(i, 2, 4)
   2856  *
   2857  * counts: 2, 3, 0, 1
   2858  *
   2859  * ;bool UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2860  * on older compilers
   2861  */
   2862 #define circular(index, from, maxCount) \
   2863   ;bool UNIQVAR(libsheepyInternalStatus) = true; \
   2864   size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
   2865   size_t UNIQVAR(frm) = (size_t)(from); \
   2866   for (size_t index = UNIQVAR(frm) ; (index != UNIQVAR(frm)) || (UNIQVAR(libsheepyInternalStatus)); index == (UNIQVAR(maxCnt)-1) ? index = 0 : index++, UNIQVAR(libsheepyInternalStatus) = false)
   2867 
   2868 /**
   2869  * range from value from down to 0 then from maxCount-1 to from+1
   2870  *
   2871  * Example:
   2872  * circularDown(i, 2, 4)
   2873  *
   2874  * counts: 2, 1, 0, 3
   2875  *
   2876  * ;bool UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2877  * on older compilers
   2878  */
   2879 #define circularDown(index, from, maxCount) \
   2880   ;bool UNIQVAR(libsheepyInternalStatus) = true; \
   2881   size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
   2882   size_t UNIQVAR(frm) = (size_t)(from); \
   2883   for (size_t index = UNIQVAR(frm) ; (index != UNIQVAR(frm)) || (UNIQVAR(libsheepyInternalStatus)); index == 0 ? index = (UNIQVAR(maxCnt)-1) : index--, UNIQVAR(libsheepyInternalStatus) = false)
   2884 
   2885 /**
   2886  * range step loop
   2887  * ;size_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2888  * on older compilers
   2889  */
   2890 #define rangeStep(index, maxCount, step) \
   2891   ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
   2892   for (size_t index = 0 ; index < UNIQVAR(maxCnt) ; index+=step)
   2893 
   2894 /**
   2895  * range down step loop, index is int64_t
   2896  */
   2897 #define rangeDownStep(index, maxCount, step) \
   2898   for (int64_t index = (maxCount)-1 ; index >= 0 ; index-=step)
   2899 
   2900 /**
   2901  * range step loop starting at value from
   2902  * ;size_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2903  * on older compilers
   2904  */
   2905 #define rangeFromStep(index, from, maxCount, step) \
   2906   ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
   2907   for (size_t index = from ; index < UNIQVAR(maxCnt) ; index+=(size_t)step)
   2908 
   2909 
   2910 /**
   2911  * loops without index
   2912  * ;size_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2913  * on older compilers
   2914  */
   2915 #define loop(maxCount) \
   2916   ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
   2917   for (size_t UNIQVAR(index) = 0 ; UNIQVAR(index) < UNIQVAR(maxCnt) ; UNIQVAR(index)++)
   2918 
   2919 /**
   2920  * loop to to index
   2921  * ;ssize_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2922  * on older compilers
   2923  */
   2924 #define loopDownTo(maxCount, to) \
   2925   ;ssize_t UNIQVAR(_to) = to;\
   2926   for (ssize_t UNIQVAR(index) = (maxCount)-1 ; UNIQVAR(index) >= UNIQVAR(_to) ; UNIQVAR(index)--)
   2927 
   2928 /**
   2929  * loop starting at value from
   2930  * ;size_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2931  * on older compilers
   2932  */
   2933 #define loopFrom(from, maxCount) \
   2934   ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
   2935   for (size_t UNIQVAR(index) = from ; UNIQVAR(index) < UNIQVAR(maxCnt) ; UNIQVAR(index)++)
   2936 
   2937 /**
   2938  * step loop
   2939  * ;size_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2940  * on older compilers
   2941  */
   2942 #define loopStep(maxCount, step) \
   2943   ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
   2944   for (size_t UNIQVAR(index) = 0 ; UNIQVAR(index) < UNIQVAR(maxCnt) ; UNIQVAR(index)+=step)
   2945 
   2946 /**
   2947  * step loop starting at value from
   2948  * ;size_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   2949  * on older compilers
   2950  */
   2951 #define loopFromStep(from, maxCount, step) \
   2952   ;size_t UNIQVAR(maxCnt) = (size_t)(maxCount); \
   2953   for (size_t UNIQVAR(index) = from ; UNIQVAR(index) < UNIQVAR(maxCnt) ; UNIQVAR(index)+=step)
   2954 
   2955 
   2956 /**
   2957  * loop on array elements
   2958  * element is a pointer to a value in the array
   2959  *
   2960  * aForEach(array, e) {
   2961  *    e->x = 0;
   2962  * }
   2963  */
   2964 #define aForEach(array, element) \
   2965   ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
   2966   for (typeof(&array[0]) element = &array[0] ; UNIQVAR(libsheepyInternalIndex) < ARRAY_SIZE(array) ; UNIQVAR(libsheepyInternalIndex)++, element = &array[UNIQVAR(libsheepyInternalIndex)])
   2967 
   2968 /**
   2969  * enumerate array elements
   2970  * index is the position of the element in the array
   2971  * index is declared as size_t and is available after the loop
   2972  * element is a pointer to a value in the array
   2973  *
   2974  * aEnumerate(array, i, e) {
   2975  *    e->x = 0;
   2976  *    printf("aEnumerate %d\n", i);
   2977  * }
   2978  */
   2979 #define aEnumerate(array, index, element) \
   2980   ; size_t index = 0 ; \
   2981   for (typeof(&array[0]) element = &array[0] ; index < ARRAY_SIZE(array) ; index++, element = &array[index])
   2982 
   2983 /**
   2984  * forEach - loop macro on list indexes
   2985  * to access the element in the loop, use *element
   2986   */
   2987 #define forEachCharP(list, element) \
   2988   for (char **element=list ; *element != NULL ; element++)
   2989 
   2990 /**
   2991  * forEach for const char** lists
   2992  */
   2993 #define forEachCCharP(list, element) \
   2994   for (const char **element=list ; *element != NULL ; element++)
   2995 
   2996 /**
   2997  * forEach - loop macro on list indexes
   2998  * to access the element in the loop, use element
   2999  * ;size_t UNIQVAR needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   3000  * on older compilers
   3001  */
   3002 #define forEachS(list, element) \
   3003   ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
   3004   for (char *element = (list)[0]; (list)[UNIQVAR(libsheepyInternalIndex)]!= NULL ; UNIQVAR(libsheepyInternalIndex)++, element = (list)[UNIQVAR(libsheepyInternalIndex)])
   3005 
   3006 /**
   3007  * forEach for const char** lists
   3008  */
   3009 #define forEachCS(list, element) \
   3010   ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
   3011   for (const char *element = (list)[0]; (list)[UNIQVAR(libsheepyInternalIndex)]!= NULL ; UNIQVAR(libsheepyInternalIndex)++, element = (list)[UNIQVAR(libsheepyInternalIndex)])
   3012 
   3013 /**
   3014  * forEach - loop macro on list indexes
   3015  */
   3016 #define forEachType(type, list, element) \
   3017   for (type **element=list ; *element != NULL ; element++)
   3018 
   3019 /**
   3020  * enumerateCharP list
   3021  * to access the element in the loop, use *element
   3022  * ;size_t needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   3023  * on older compilers
   3024  */
   3025 #define enumerateCharP(list, element, index) \
   3026   ;size_t index = 0; \
   3027   for (char **element=list; *element != NULL ; element++, index++)
   3028 
   3029 /**
   3030  * enumerateCCharP const list
   3031  * to access the element in the loop, use *element
   3032  * ;size_t needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   3033  * on older compilers
   3034  */
   3035 #define enumerateCCharP(list, element, index) \
   3036   ;size_t index = 0; \
   3037   for (const char **element=list; *element != NULL ; element++, index++)
   3038 
   3039 /**
   3040  * enumerateS list
   3041  * to acess the element in the loop, use element
   3042  * ;size_t needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   3043  * on older compilers
   3044  */
   3045 #define enumerateS(list, element, index) \
   3046   ;size_t index = 0; \
   3047   for (char *element=(list)[0]; element != NULL ; index++, element = (list)[index])
   3048 
   3049 /**
   3050  * enumerateCS const list
   3051  * to acess the element in the loop, use element
   3052  * ;size_t needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   3053  * on older compilers
   3054  */
   3055 #define enumerateCS(list, element, index) \
   3056   ;size_t index = 0; \
   3057   for (const char *element=(list)[0]; element != NULL ; index++, element = (list)[index])
   3058 
   3059 /**
   3060  * enumerateType list
   3061  * ;size_t needed to avoid: error: a label can only be part of a statement and a declaration is not a statement
   3062  * on older compilers
   3063  */
   3064 #define enumerateType(type, list, element, index) \
   3065   ;size_t index = 0; \
   3066   for (type **element=list; *element != NULL ; element++, index++)
   3067 
   3068 /**
   3069  * loop for linked lists from startNode to last
   3070  *
   3071  * node must be a pointer to a struct with a next member pointing
   3072  * to the next node in the list
   3073  *
   3074  * when node->next is NULL, the list end is reached
   3075  * */
   3076 #define lForEach(node, startNode)\
   3077   for(var node = startNode; node ; node = (node)->next)
   3078 
   3079 /**
   3080  * loop for linked lists from startNode to head
   3081  *
   3082  * node must be a pointer to a struct with a prev member pointing
   3083  * to the previous node in the list
   3084  *
   3085  * when node->prev is NULL, the list head is reached
   3086  */
   3087 #define lForEachDown(node, startNode)\
   3088   for(var node = startNode; node ; node = (node)->prev)
   3089 
   3090 #define lForEachPrev lForEachDown
   3091 
   3092 // user defined function for sort functions
   3093 typedef int (*shCmpt)(const void * a, const void * b);
   3094 
   3095 // duplicate and sort
   3096 char **listSortS(char **list) MUST_CHECK;
   3097 char **iListSortS(char ***list) MUST_CHECK;
   3098 char **listSortFS(char **list, shCmpt compareFunction) MUST_CHECK;
   3099 char **iListSortFS(char ***list, shCmpt compareFunction) MUST_CHECK;
   3100 
   3101 // ignore case, duplicate and sort
   3102 char **icListSortS(char **list) MUST_CHECK;
   3103 char **iicListSortS(char ***list) MUST_CHECK;
   3104 
   3105 // open text file and return lines in list
   3106 char **readText(const char *filePath) MUST_CHECK;
   3107 
   3108 // read opened text file and return lines in list
   3109 // the file is left open
   3110 char **readStream(FILE *fp) MUST_CHECK;
   3111 
   3112 // write text file
   3113 bool writeText(const char *filePath, char **list) MUST_CHECK;
   3114 bool writeCText(const char *filePath, const char **list) MUST_CHECK;
   3115 
   3116 // write buffer
   3117 bool writeStream(FILE *fp, char **list) MUST_CHECK;
   3118 bool writeCStream(FILE *fp, const char **list) MUST_CHECK;
   3119 
   3120 // append text to file
   3121 bool appendText(const char *filePath, char **list) MUST_CHECK;
   3122 bool appendCText(const char *filePath, const char **list) MUST_CHECK;
   3123 
   3124 // execOut
   3125 char **execOut(const char *cmd) MUST_CHECK;
   3126 // convenience define
   3127 #define execOutf systemOutf
   3128 #define execf systemf
   3129 
   3130 // system command with formatting
   3131 char **systemOutf(const char *fmt, ...) MUST_CHECK;
   3132 // convenience define
   3133 #define systemOut execOut
   3134 int systemf(const char *fmt, ...) MUST_CHECK;
   3135 
   3136 // system commands and log
   3137 #define logSystem(cmd) funcbegin\
   3138     var UNIQVAR(cm) = cmd;\
   3139     logI("%s",UNIQVAR(cm));\
   3140     system   (UNIQVAR(cm));\
   3141   funcend
   3142 #define logExec logSystem
   3143 #define logSystemOut(cmd) ({\
   3144     var UNIQVAR(cm) = cmd;\
   3145     logI("%s",UNIQVAR(cm));\
   3146     systemOut(UNIQVAR(cm));\
   3147   })
   3148 #define logExecOut logSystemOut
   3149 #define logSystemOutf(fmt, ...) ({\
   3150     logI      (fmt, __VA_ARGS__);\
   3151     systemOutf(fmt, __VA_ARGS__);})
   3152 #define logExecOutf logSystemOutf
   3153 #define logSystemf(fmt, ...) ({\
   3154     logI   (fmt, __VA_ARGS__);\
   3155     systemf(fmt, __VA_ARGS__);})
   3156 #define logExecf logSystemf
   3157 
   3158 // run command and return exit code from command (not system return value like system, systemf and systemNFree)
   3159 #define command(cmd) commandF(cmd, __LINE__, __func__, __FILE__)
   3160 int commandF(const char *cmd, int line, const char *thisFunc, const char *thisFileName) MUST_CHECK;
   3161 #define commandf(...) commandfF(__LINE__, __func__, __FILE__, __VA_ARGS__)
   3162 int commandfF(int line, const char *thisFunc, const char *thisFileName, const char *fmt, ...) MUST_CHECK;
   3163 #define commandNFree(cmd) commandNFreeF(cmd, __LINE__, __func__, __FILE__)
   3164 int commandNFreeF(char *cmd, int line, const char *thisFunc, const char *thisFileName) MUST_CHECK;
   3165 #define commandOut execOut
   3166 #define commandOutf systemOutf
   3167 
   3168 // log then run command and return exit code from command (not system return value like system, systemf and systemNFree)
   3169 #define logCommand(cmd) funcbegin\
   3170     var UNIQVAR(cm) = cmd;\
   3171     logI("%s",UNIQVAR(cm));\
   3172     command  (UNIQVAR(cm));\
   3173   funcend
   3174 
   3175 #define logCommandf(fmt, ...) funcbegin\
   3176     logI    (fmt, __VA_ARGS__);\
   3177     commandf(fmt, __VA_ARGS__);\
   3178   funcend
   3179 
   3180 #define logCommandNFree(cmd) funcbegin\
   3181     var UNIQVAR(cm) = cmd;\
   3182     logI   ("%s",UNIQVAR(cm));\
   3183     commandNFree(UNIQVAR(cm));\
   3184   funcend
   3185 
   3186 #define logCommandOut logExecOut
   3187 #define logCommandOutf logExecOutf
   3188 
   3189 // compare lists
   3190 bool listEqS(char **list1, char **list2) MUST_CHECK;
   3191 bool listEqCS(char **list1, const char **list2) MUST_CHECK;
   3192 bool listEqC1S(const char **list1, char **list2) MUST_CHECK;
   3193 bool listEqCCS(const char **list1, const char **list2) MUST_CHECK;
   3194 
   3195 // has
   3196 bool listHasS(char **list, const char *string) MUST_CHECK;
   3197 bool listHasCS(const char **list, const char *string) MUST_CHECK;
   3198 bool listHasCharS(char **list, char c) MUST_CHECK;
   3199 bool listHasCharCS(const char **list, char c) MUST_CHECK;
   3200 
   3201 // indexOf
   3202 ssize_t listIndexOfS(char **list, const char *string) MUST_CHECK;
   3203 ssize_t listIndexOfCS(const char **list, const char *string) MUST_CHECK;
   3204 ssize_t listIndexOfCharS(char **list, char c) MUST_CHECK;
   3205 ssize_t listIndexOfCharCS(const char **list, char c) MUST_CHECK;
   3206 
   3207 // list binary search string
   3208 ssize_t listBinarySearchS(char **list, const char *string) MUST_CHECK;
   3209 ssize_t listBinarySearchCharS(char **list, char c) MUST_CHECK;
   3210 
   3211 // duplicate and uniquify
   3212 char **listUniqS(char **list) MUST_CHECK;
   3213 char **iListUniqS(char ***list) MUST_CHECK;
   3214 
   3215 // ignore case and compare lists
   3216 bool icListEqS(char **list1, char **list2) MUST_CHECK;
   3217 bool icListEqCS(char **list1, const char **list2) MUST_CHECK;
   3218 bool icListEqC1S(const char **list1, char **list2) MUST_CHECK;
   3219 bool icListEqCCS(const char **list1, const char **list2) MUST_CHECK;
   3220 
   3221 // ignore case has
   3222 bool icListHasS(char **list, const char *string) MUST_CHECK;
   3223 bool icListHasCharS(char **list, char c) MUST_CHECK;
   3224 bool icListHasCS(const char **list, const char *string) MUST_CHECK;
   3225 bool icListHasCharCS(const char **list, char c) MUST_CHECK;
   3226 
   3227 // ignore case indexOf
   3228 ssize_t icListIndexOfS(char **list, const char *string) MUST_CHECK;
   3229 ssize_t icListIndexOfCS(const char **list, const char *string) MUST_CHECK;
   3230 ssize_t icListIndexOfCharS(char **list, char c) MUST_CHECK;
   3231 ssize_t icListIndexOfCharCS(const char **list, char c) MUST_CHECK;
   3232 
   3233 // ignore case list binary search string
   3234 ssize_t icListBinarySearchS(char **list, const char *string) MUST_CHECK;
   3235 ssize_t icListBinarySearchCharS(char **list, char c) MUST_CHECK;
   3236 
   3237 // ignore case, duplicate and uniquify
   3238 char **icListUniqS(char **list) MUST_CHECK;
   3239 char **iicListUniqS(char ***list) MUST_CHECK;
   3240 
   3241 // duplicate and compact
   3242 char **listCompactS(char **list) MUST_CHECK;
   3243 char **iListCompactS(char ***list) MUST_CHECK;
   3244 
   3245 void btraceEnable(void);
   3246 void btraceDisable(void);
   3247 bool btraceConfig(void) MUST_CHECK;
   3248 
   3249 // get backtrace
   3250 char **btrace(void);
   3251 
   3252 // print backtrace
   3253 #if __APPLE__
   3254 // TODO readelf missing in macOS
   3255 #define logBtrace
   3256 #else
   3257 #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("---");}
   3258 #endif
   3259 
   3260 extern bool btraceCfg;
   3261 
   3262 /** print backtrace in error messages, default is on, use btraceEnable and btraceDisable to configure */
   3263 #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("---");} }
   3264 
   3265 
   3266 // **************************
   3267 // void ** lists
   3268 // **************************
   3269 
   3270 // create empty list
   3271 #define listEmpty(list) \
   3272   do {\
   3273     list = malloc(1 * sizeof(void *)); \
   3274     if (list) list[0] = NULL; \
   3275   } while(0);
   3276 
   3277 void **listEmptyF(void) MUST_CHECK;
   3278 void **iListEmptyF(void ***list) MUST_CHECK;
   3279 
   3280 // false when there are elements in the list
   3281 bool listIsEmpty(void **list) MUST_CHECK;
   3282 
   3283 // createList(...)
   3284 void **listCreateF(void *paramType, ...) MUST_CHECK;
   3285 #define listCreate(...) listCreateF(NULL, __VA_ARGS__, NULL)
   3286 
   3287 // copy array to new list
   3288 void **listFromArray(void **array, size_t size) MUST_CHECK;
   3289 
   3290 // push and pop (append) element
   3291 // modifies the list
   3292 void **listPush(void ***list, void *s) MUST_CHECK;
   3293 
   3294 // return last element and remove it from the list
   3295 void *listPop(void ***list) MUST_CHECK;
   3296 
   3297 // prepend and dequeue (append) element
   3298 // modifies the list
   3299 void **listPrepend(void ***list, void *s) MUST_CHECK;
   3300 
   3301 // return fist element and remove it from the list
   3302 void *listDequeue(void ***list) MUST_CHECK;
   3303 
   3304 // freeList
   3305 void listFree(void **list);
   3306 
   3307 // free many void**
   3308 void listFreeManyF(void **paramType, ...);
   3309 #define listFreeMany(...) listFreeManyF(NULL, __VA_ARGS__, NULL)
   3310 
   3311 // length
   3312 size_t listLength(void **list) MUST_CHECK;
   3313 
   3314 // list get - get an element at python index
   3315 void *listGet(void **list, int64_t index) MUST_CHECK;
   3316 
   3317 // list set - replace a string at python index
   3318 void **listSet(void **list, int64_t index, void *s) MUST_CHECK;
   3319 
   3320 // duplicate list
   3321 void **listDup(void **list) MUST_CHECK;
   3322 
   3323 // duplicate and reverse list
   3324 void **listReverse(void **list) MUST_CHECK;
   3325 void **iListReverse(void ***list) MUST_CHECK;
   3326 
   3327 // listCatS: f(l1, l2, l3)
   3328 void **listCatF(void **paramType, ...) MUST_CHECK;
   3329 #define listCat(...) listCatF(NULL, __VA_ARGS__, NULL)
   3330 
   3331 // append lists
   3332 void **listAppend(void ***list1, void **list2) MUST_CHECK;
   3333 
   3334 // add lists
   3335 void **listAdd(void **list1, void **list2) MUST_CHECK;
   3336 
   3337 // slice - python style indexes 0..len-1 -1..-len+1
   3338 void **listSlice(void **list, int64_t start, int64_t end) MUST_CHECK;
   3339 void **iListSlice(void ***list, int64_t start, int64_t end) MUST_CHECK;
   3340 
   3341 // insert list in list
   3342 void **listInsert(void **list, int64_t index, void **toInsert) MUST_CHECK;
   3343 void **iListInsert(void ***list, int64_t index, void **toInsert) MUST_CHECK;
   3344 
   3345 // del - python style indexes 0..len-1 -1..-len+1
   3346 void **listDel(void **list, int64_t start, int64_t end) MUST_CHECK;
   3347 void **iListDel(void ***list, int64_t start, int64_t end) MUST_CHECK;
   3348 //NOT NEEDED same as iListDel - void **iListRemove(void ***list, int64_t start, int64_t end);
   3349 
   3350 // duplicate and sort
   3351 //TODO void **listSort(void **list);
   3352 //TODO void iListSort(void ***list);
   3353 
   3354 // compare lists
   3355 //TODO bool listEq(void **list1, void **list2);
   3356 
   3357 // indexOf
   3358 //TODO ssize_t listIndexOf(void **list, const void *string);
   3359 
   3360 // list binary search string
   3361 //TODO ssize_t listBinarySearch(void **list, const void *string);
   3362 
   3363 // duplicate and uniquify
   3364 //TODO void **listUniq(void **list);
   3365 //TODO void iListUniq(void ***list);
   3366 
   3367 // duplicate and compact
   3368 //TODO void **listCompact(void **list);
   3369 //TODO void iListCompact(void ***list);
   3370 
   3371 // create name variable and allocate it on heap
   3372 #define newPtr(name, type)\
   3373   ;type *name = malloc(sizeof(type))
   3374 
   3375 // create name variable and calloc it on heap
   3376 #define new0Ptr(name, type)\
   3377   ;type *name = calloc(1, sizeof(type))
   3378 
   3379 // allocate struct on heap and assign address
   3380 #define allocAPtr(name) name = malloc(sizeof(*(name)))
   3381 
   3382 // calloc struct on heap and assign address
   3383 #define callocAPtr(name) name = calloc(1, sizeof(*(name)))
   3384 
   3385 // create name variable and allocate array of type on heap
   3386 #define newArray(name, type, count)\
   3387   ;type *name = malloc((count) * sizeof(type))
   3388 
   3389 // create name variable and calloc array of type on heap
   3390 #define new0Array(name, type, count)\
   3391   ;type *name = calloc(count, sizeof(type))
   3392 
   3393 // allocate array
   3394 #define allocArray(name, count) malloc((count) * sizeof(*(name)))
   3395 
   3396 // allocate and assign array
   3397 #define allocAArray(name, count) name = malloc((count) * sizeof(*(name)))
   3398 
   3399 // calloc array
   3400 #define callocArray(name, count) calloc(count,  sizeof(*(name)))
   3401 
   3402 // calloc and assign array
   3403 #define callocAArray(name, count) name = calloc(count,  sizeof(*(name)))
   3404 
   3405 // realloc array
   3406 #define reallocArray(name, count) realloc(name, (count) * sizeof(*(name)))
   3407 
   3408 /**
   3409  * slice - dynamic array in one chunk of memory (similar to vector and slab below)
   3410  *
   3411  * This is a simple dynamic array holding element count and the data
   3412  *
   3413  * this type of array has a dynamic element count
   3414  * pushing elements into the array increases the element count
   3415  * poping elements only decreases the element count, call sliceFit to realloc the slice
   3416  *
   3417  * no sanity checks are done
   3418  *
   3419  * the prefix is slice
   3420  *
   3421  * Usage:
   3422  *
   3423  * to declare a slice:
   3424  *
   3425  * sliceT(typeName, type);
   3426  *
   3427  * typeName slce;
   3428  *
   3429  * sliceInit(&slce);
   3430  * or
   3431  * sliceInitCount(&slce, 17);
   3432  *
   3433  * sliceAppend(&slce, value);
   3434  *
   3435  * // get an element
   3436  * int a                = sliceAt(&slce, 0);
   3437  *
   3438  * set
   3439  * sliceAt(&slce, 1) = 3;
   3440  *
   3441  * sliceFree(&slce);
   3442  *
   3443  * Slice variables:
   3444  * slce.array:    elements
   3445  * slce.count:    current element count
   3446  *
   3447  * Note: some functions are macros to be able to have structs as element and
   3448  *       access the struct members directly, for example:
   3449  *         sliceLast(chan).a = 0;
   3450  */
   3451 
   3452 /** number of elements added by sliceAlloc */
   3453 #define sliceSz 1
   3454 
   3455 /**
   3456  * declares type for slice
   3457  *
   3458  * \param
   3459  * typeName slice type name
   3460  * \param
   3461  * element type of elements (int, struct, pointer...)
   3462  */
   3463 #define sliceT(typeName, elementType)\
   3464   typedef struct {\
   3465     size_t count;\
   3466     elementType *array;\
   3467   } typeName
   3468 
   3469 #define createSlice(typeName, name) ;typeName name; sliceInit(&name)
   3470 
   3471 #define createSliceCount(typeName, name, count) ;typeName name; sliceInitCount(&name, count)
   3472 
   3473 #define createSliceClearCount(typeName, name, count) ;typeName name; sliceCalloc(&name, count)
   3474 
   3475 #define createAllocateSlice(typeName, name) ;typeName *name = calloc(1, sizeof(typeName))
   3476 
   3477 #define createAllocateSliceCount(typeName, name, count) ;typeName *name = calloc(1, sizeof(typeName)); sliceInitCount(name, count)
   3478 
   3479 #define createAllocateSliceClearCount(typeName, name, count) ;typeName *name = calloc(1, sizeof(typeName)); sliceCalloc(name, count)
   3480 
   3481 #define sliceTerminate(name) if (name) sliceFree(name);free(name)
   3482 
   3483 /**
   3484  * initialize empty slice
   3485  *
   3486  * \param
   3487  * name variable name for slice
   3488  */
   3489 #define sliceInit(name) do{\
   3490     (name)->array    = NULL;\
   3491     (name)->count    = 0;\
   3492   } while(0)
   3493 
   3494 /**
   3495  * initialize slice and count
   3496  *
   3497  * \param
   3498  * name variable name for slice
   3499  * \param
   3500  * count initial element count for name type
   3501  */
   3502 #define sliceInitCount(name, countInt) do{\
   3503     var UNIQVAR(c)   = countInt;\
   3504     /* TODO check if countInt is 0 then +1 */\
   3505     (name)->array    = malloc(UNIQVAR(c) * sizeof (name)->array[0]);\
   3506     (name)->count    = UNIQVAR(c);\
   3507   } while(0)
   3508 
   3509 /**
   3510  * initialize slice and count and set slice data to 0
   3511  *
   3512  * \param
   3513  * name variable name for slice
   3514  * \param
   3515  * count initial element count for name type
   3516  */
   3517 #define sliceCalloc(name, countInt) do{\
   3518     var UNIQVAR(c)   = countInt;\
   3519     (name)->array    = calloc(UNIQVAR(c), sizeof (name)->array[0]);\
   3520     (name)->count    = 0;\
   3521   } while(0)
   3522 
   3523 /**
   3524  * resize slice (even empty slices)
   3525  */
   3526 #define sliceResize(name, countInt) do{\
   3527   var UNIQVAR(c) = countInt;\
   3528   if ((name)->array) {\
   3529     /* realloc */\
   3530     (name)->array = realloc((name)->array, sizeof((name)->array[0]) * UNIQVAR(c));\
   3531   }\
   3532   else {\
   3533     /* was empty */\
   3534     (name)->array = malloc(sizeof((name)->array[0]) * UNIQVAR(c));\
   3535   }\
   3536   /* element count when shrinking */\
   3537   if (UNIQVAR(c) < (name)->count) (name)->count = UNIQVAR(c);\
   3538   } while(0)
   3539 
   3540 /**
   3541  * resize slice and clear the new elements with memset
   3542  * even empty slices can be resized and cleared
   3543  */
   3544 #define sliceClearResize(name, countInt) do{\
   3545   var UNIQVAR(c) = countInt;\
   3546   if ((name)->array) {\
   3547     /* realloc */\
   3548     (name)->array = realloc((name)->array, sizeof((name)->array[0]) * UNIQVAR(c));\
   3549     if ((name)->count < UNIQVAR(c)) {\
   3550       /* there are new elements */\
   3551       memset(&(name)->array[(name)->count], 0, (UNIQVAR(c) - (name)->count) * sizeof (name)->array[0]);\
   3552     }\
   3553   }\
   3554   else {\
   3555     /* was empty */\
   3556     (name)->array = calloc(UNIQVAR(c), sizeof((name)->array[0]));\
   3557   }\
   3558   /* element count when shrinking */\
   3559   if (UNIQVAR(c) < (name)->count) (name)->count = UNIQVAR(c);\
   3560   } while(0)
   3561 
   3562 /**
   3563  * free the internal buffers
   3564  *
   3565  * \param
   3566  * name slice
   3567  */
   3568 #define sliceFree(name) free((name)->array)
   3569 
   3570 /**
   3571  * element type in slice
   3572  */
   3573 #define sliceElemType(name) typeof((name)->array[0])
   3574 
   3575 /**
   3576  * element pointer type in slice
   3577  */
   3578 #define sliceElemPtrType(name) typeof(&(name)->array[0])
   3579 
   3580 /**
   3581  * duplicate slice
   3582  */
   3583 #define sliceDup(name) ({\
   3584     typeof(*(name)) dest;\
   3585     sliceInitCount(&dest, (name)->count);\
   3586     if ((name)->array) {\
   3587       memcpy(dest.array, (name)->array, (name)->count * sizeof (name)->array[0]);\
   3588       dest.count = (name)->count;\
   3589     }\
   3590     /* return */ dest;\
   3591   })
   3592 
   3593 /**
   3594  * assign slice from to slice to
   3595  * the data is shared between slice from and slice to
   3596  * the counts are not shared
   3597  *
   3598  * NO need for this macro, do like this:
   3599  * *to = *from;
   3600  */
   3601 /* #define sliceAgn(to, from) do{\
   3602     (to)->count = (from)->count;\
   3603     (to)->array = (from)->array;\
   3604   } while(0) */
   3605 
   3606 /**
   3607  * declare dest slice and duplicate slice
   3608  */
   3609 #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;}
   3610 
   3611 /**
   3612  * duplicate slice to already declared dest slice
   3613  */
   3614 #define sliceBDup(name, dest) do{\
   3615   var UNIQVAR(dst) = dest;\
   3616   sliceResize(UNIQVAR(dst), (name)->count);\
   3617   if ((name)->array) {\
   3618     memcpy(UNIQVAR(dst)->array, (name)->array, (name)->count * sizeof (name)->array[0]);\
   3619     UNIQVAR(dst)->count = (name)->count;\
   3620   }\
   3621   } while(0)
   3622 
   3623 
   3624 /**
   3625  * direct access to underlying array
   3626  */
   3627 #define sliceData(name) (name)->array
   3628 
   3629 /**
   3630  * copy data from array to slice
   3631  */
   3632 #define sliceFrom(name, arrayIn, countInt) do{\
   3633     var UNIQVAR(c) = countInt;\
   3634     var UNIQVAR(a) = arrayIn;\
   3635     if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
   3636       sliceResize(name, UNIQVAR(c));\
   3637       memcpy((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof UNIQVAR(a)[0]);\
   3638       (name)->count = UNIQVAR(c);\
   3639     }\
   3640   } while(0)
   3641 
   3642 /**
   3643  * mirror a range in a slice
   3644  * the data is not copied to dest slice, to copy data see sliceCopy or sliceBCopy
   3645  */
   3646 #define sliceMirror(name, start, end) ({\
   3647   var UNIQVAR(strt) = start;\
   3648   typeof(*(name)) UNIQVAR(r);\
   3649   UNIQVAR(r).array = slicePtr(name, UNIQVAR(strt));\
   3650   UNIQVAR(r).count = end - UNIQVAR(strt);\
   3651   UNIQVAR(r);\
   3652   })
   3653 
   3654 /**
   3655  * mirror a range in a slice
   3656  * the data is not copied to dest slice, to copy data see sliceCopy or sliceBCopy
   3657  *
   3658  * name can be slice, vector or slab
   3659  * dest must be slice
   3660  */
   3661 #define sliceBMirror(name, dest, start, end) do{\
   3662   var UNIQVAR(strt)   = start;\
   3663   var UNIQVAR(dst)    = dest;\
   3664   UNIQVAR(dst)->array = slicePtr(name, UNIQVAR(strt));\
   3665   UNIQVAR(dst)->count = end - UNIQVAR(strt);\
   3666   } while(0)
   3667 
   3668 /**
   3669  * mirror from array to slice
   3670  * the data is not copied to dest slice, to copy data see sliceCopy or sliceBCopy
   3671  */
   3672 #define sliceMirrorFrom(name, array, countInt) do{\
   3673   var UNIQVAR(strt) = start;\
   3674   (name)->array     = array;\
   3675   (name)->count     = countInt;\
   3676   } while(0)
   3677 
   3678 
   3679 /**
   3680  * set 0 in slice elements
   3681  * count is unchanged
   3682  */
   3683 #define sliceClear(name) do{\
   3684     if ((name)->array)\
   3685       memset((name)->array, 0, (name)->count * sizeof (name)->array[0]);\
   3686   } while(0)
   3687 
   3688 #define sliceClearRange(name, start, end) do{\
   3689     if ((name)->array)\
   3690       memset((name)->array + start, 0, (end-start) * sizeof (name)->array[0]);\
   3691   } while(0)
   3692 
   3693 /**
   3694  * Empty slice
   3695  * Set count to 0
   3696  * Allocated buffers in the slice must be freed before running sliceEmpty
   3697  */
   3698 #define sliceEmpty(name) (name)->count = 0
   3699 
   3700 /**
   3701  * is slice Empty
   3702  */
   3703 #define sliceIsEmpty(name) ((name)->count == 0 || !(name)->array)
   3704 
   3705 /**
   3706  * realloc slice to count
   3707  */
   3708 #define sliceFit(name) do{\
   3709     sliceResize(name, (name)->count);\
   3710   } while(0)
   3711 
   3712 /**
   3713  * return element count
   3714  */
   3715 #define sliceCount(name) (name)->count
   3716 
   3717 /**
   3718  * size of slice element
   3719  */
   3720 #define sliceElemSize(name) sizeof((name)->array[0])
   3721 
   3722 /**
   3723  * allocate an element
   3724  * only when the slice is full
   3725  */
   3726 #define sliceAlloc(name) do{\
   3727     if (!(name)->array) {\
   3728       (name)->array    = malloc(sliceSz * sizeof (name)->array[0]);\
   3729     }\
   3730     else {\
   3731       (name)->array    = realloc((name)->array, ((name)->count + sliceSz) * sizeof (name)->array[0]);\
   3732     }\
   3733   } while(0)
   3734 
   3735 /**
   3736  * clear (set 0) in element at index
   3737  */
   3738 #define sliceClearElem(name, index) memset(&(name)->array[index], 0, sizeof (name)->array[0])
   3739 
   3740 /**
   3741  * push element and expand the slice
   3742  * no data (random) is set in the new element
   3743  *
   3744  * \param
   3745  * name slice
   3746  */
   3747 #define slicePush(name) do {\
   3748     sliceAlloc(name);\
   3749     (name)->count++;\
   3750   } while(0)
   3751 
   3752 /**
   3753  * append element and expand the slice
   3754  *
   3755  * \param
   3756  * name slice
   3757  * \param
   3758  * v element to push
   3759  */
   3760 #define sliceAppend(name, v) do{\
   3761     slicePush(name);\
   3762     sliceLast(name) = v;\
   3763   } while(0)
   3764 
   3765 
   3766 /**
   3767  * push element and expand the slice
   3768  * the new element is cleared
   3769  *
   3770  * \param
   3771  * name slice
   3772  */
   3773 #define sliceClearPush(name) do{\
   3774     slicePush(name);\
   3775     sliceClearElem(name, (name)->count - 1);\
   3776   } while(0)
   3777 
   3778 /**
   3779  * pop element
   3780  * the element count is decreased
   3781  *
   3782  * NOTE: using comma operator to avoid warning
   3783  * warning: operation on ‘b.head’ may be undefined [-Wsequence-point]
   3784  *
   3785  *
   3786  * \param
   3787  * name slice
   3788  */
   3789 #define slicePop(name) ((name)->count--, (name)->array[(name)->count])
   3790 
   3791 /**
   3792  * delete the last element
   3793  * useful for avoiding warning: right-hand operand of comma expression has no effect
   3794  * when the poped value is not used
   3795  */
   3796 #define sliceDelLast(name) ((name)->count--)
   3797 
   3798 /**
   3799  * set value at index and clearResize slice when index is outside slice count
   3800  */
   3801 #define sliceSet(name, index, v) do{\
   3802     var UNIQVAR(idx) = index;\
   3803     if (UNIQVAR(idx) >= (name)->count) {\
   3804       /* clear and resize */\
   3805       sliceClearResize(name, UNIQVAR(idx)+1);\
   3806     }\
   3807     sliceAt(name, UNIQVAR(idx)) = v;\
   3808   } while(0)
   3809 
   3810 /**
   3811  * get / set element at index
   3812  *
   3813  * \param
   3814  * name slice
   3815  * \param
   3816  * index index in array
   3817  */
   3818 #define sliceAt(name, index) ((name)->array[index])
   3819 
   3820 /**
   3821  * get pointer to element at index
   3822  *
   3823  * \param
   3824  * name slice
   3825  * \param
   3826  * index index in array
   3827  */
   3828 #define slicePtr(name, index) ((name)->array + index)
   3829 
   3830 /**
   3831  * last element
   3832  *
   3833  * \param
   3834  * name slice
   3835  */
   3836 #define sliceLast(name) ((name)->array[(name)->count-1])
   3837 
   3838 /**
   3839  * pointer to last element
   3840  *
   3841  * \param
   3842  * name slice
   3843  */
   3844 #define sliceLastPtr(name) ((name)->array + (name)->count - 1)
   3845 
   3846 /**
   3847  * index of last element
   3848  */
   3849 #define sliceLastIndex(name) ((name)->count - 1)
   3850 
   3851 
   3852 /**
   3853  * first element
   3854  *
   3855  * \param
   3856  * name slice
   3857  */
   3858 #define sliceFirst(name) ((name)->array[0])
   3859 
   3860 
   3861 /**
   3862  * write the slice content to filename file
   3863  * No NULL checks are done on the parameters
   3864  *
   3865  * \param
   3866  *    filename file name string
   3867  */
   3868 #define sliceWriteFilename(name, filename) do {\
   3869     FILE *UNIQVAR(f) = fopen(filename, "w");\
   3870     if (UNIQVAR(f)) {\
   3871       fwrite((name)->array, sizeof((name)->array[0]), sliceCount(name), UNIQVAR(f));\
   3872       fclose(UNIQVAR(f));\
   3873     }\
   3874   } while(0)
   3875 
   3876 /**
   3877  * write the slice content to disk
   3878  * No NULL checks are done on the parameters
   3879  *
   3880  * \param
   3881  *    file already opened file
   3882  */
   3883 #define sliceWrite(name, file) fwrite((name)->array, sizeof((name)->array[0]), sliceCount(name), file)
   3884 
   3885 /**
   3886  * read a slice from filename file
   3887  * No NULL checks are done on the parameters
   3888  *
   3889  * \param
   3890  * filename file name string
   3891  */
   3892 #define sliceReadFilename(name, filename) do {\
   3893     if (fileExists(filename)) {\
   3894       size_t UNIQVAR(sz) = fileSize(filename);\
   3895       FILE *UNIQVAR(f) = fopen(filename, "r");\
   3896       if (UNIQVAR(f)) {\
   3897         range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
   3898           slicePush(name);\
   3899           fread(sliceLastPtr(name), 1, sizeof((name)->array[0]), UNIQVAR(f));\
   3900         }\
   3901         fclose(UNIQVAR(f));\
   3902       }\
   3903     }\
   3904   } while(0)
   3905 
   3906 /**
   3907  * read a slice from disk
   3908  * No NULL checks are done on the parameters
   3909  *
   3910  * \param
   3911  *    file already opened file
   3912  */
   3913 #define sliceRead(name, file) do {\
   3914     fseek(file, 0 , SEEK_END);\
   3915     size_t UNIQVAR(sz) = ftell(file);\
   3916     fseek(file, 0 , SEEK_SET);\
   3917     range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
   3918       slicePush(name);\
   3919       fread(sliceLastPtr(name), 1, sizeof((name)->array[0]), file);\
   3920     }\
   3921   } while(0)
   3922 
   3923 
   3924 /**
   3925  * loop index on slice elements
   3926  *
   3927  * For example:
   3928  * forEachV(vec, i) {
   3929  *   sliceAt(vec, i) = 0;
   3930  * }
   3931  */
   3932 #define forEachSc(name, index) range(index, (name)->count)
   3933 
   3934 /**
   3935  * loop on slice elements
   3936  * element is a pointer to a value in the array
   3937  *
   3938  * sliceForEach(&slc, e) {
   3939  *    e->x = 0;
   3940  * }
   3941  */
   3942 #define sliceForEach(name, element) \
   3943   ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
   3944   for (sliceElemPtrType(name) element = slicePtr(name, 0) ; UNIQVAR(libsheepyInternalIndex) < (name)->count ; UNIQVAR(libsheepyInternalIndex)++, element = slicePtr(name, UNIQVAR(libsheepyInternalIndex)))
   3945 
   3946 /**
   3947  * enumerate slice elements
   3948  * index is the position of the element in the array
   3949  * index is declared as size_t and is available after the loop
   3950  * element is a pointer to a value in the array
   3951  *
   3952  * sliceEnumerate(&slc, i, e) {
   3953  *    e->x = 0;
   3954  *    printf("sliceEnumerate %d\n", i);
   3955  * }
   3956  */
   3957 #define sliceEnumerate(name, index, element) \
   3958   ; size_t index = 0 ; \
   3959   for (sliceElemPtrType(name) element = slicePtr(name, 0) ; index < (name)->count ; index++, element = slicePtr(name, index))
   3960 
   3961 /**
   3962  * insert an element at index
   3963  * the data is moved to create space for the new element
   3964  * to set data at the new element, use sliceAt(name, index) = value;
   3965  */
   3966 #define sliceInject(name, index) do {\
   3967   var UNIQVAR(idx) = index;\
   3968   slicePush(name);\
   3969   if (index < sliceCount(name)) {\
   3970       memmove(slicePtr(name, UNIQVAR(idx) +1), slicePtr(name, UNIQVAR(idx)), ((name)->count - UNIQVAR(idx)-1) * sizeof (name)->array[0]);\
   3971     }\
   3972   } while(0)
   3973 
   3974 /**
   3975  * prepend element
   3976  *
   3977  * \param
   3978  * name slice
   3979  * \param
   3980  * v element to prepend
   3981  */
   3982 #define slicePrepend(name, v) do {\
   3983     sliceInject(name, 0);\
   3984     sliceAt(name, 0) = v;\
   3985   } while(0)
   3986 
   3987 /**
   3988  * dequeue element
   3989  *
   3990  * \param
   3991  * name slice
   3992  */
   3993 #define sliceDequeue(name) ({\
   3994     var r = sliceAt(name, 0);\
   3995     sliceDelFirst(name);\
   3996     /* return */r;\
   3997   })
   3998 
   3999 /**
   4000  * delete first element in slice
   4001  * the data is moved when count > 1
   4002  */
   4003 #define sliceDelFirst(name) do {\
   4004     if ((name)->count) {\
   4005       if ((name)->count > 1) {\
   4006         /* move elements */\
   4007         memcpy((name)->array, (name)->array +1 , ((name)->count - 1) * sizeof (name)->array[0]);\
   4008       }\
   4009       (name)->count--;\
   4010     }\
   4011   } while(0)
   4012 
   4013 
   4014 /**
   4015  * delete an element in slice
   4016  * the data is moved when index < (count-1)
   4017  * when index = count -1, the last element is deleted and no data is moved
   4018  */
   4019 #define sliceDelElem(name, index) do {\
   4020   var UNIQVAR(idx) = index;\
   4021   if ((size_t)UNIQVAR(idx) < (size_t)sliceLastIndex(name)) {\
   4022     /* move elements */\
   4023     memmove(slicePtr(name, UNIQVAR(idx)), slicePtr(name, UNIQVAR(idx) +1), ((name)->count - (UNIQVAR(idx) +1)) * sizeof (name)->array[0]);\
   4024   }\
   4025   (name)->count--;\
   4026   } while(0)
   4027 
   4028 /**
   4029  * delete range in slice
   4030  * start must be between 0 and last index
   4031  * end must be between 1 and count
   4032  */
   4033 #define sliceDel(name, start, end) do {\
   4034   var UNIQVAR(strt) = start;\
   4035   var UNIQVAR(ed)   = end;\
   4036   if (UNIQVAR(ed) < (name)->count and UNIQVAR(strt) < UNIQVAR(ed)) {\
   4037     /* move elements */\
   4038     memmove(slicePtr(name, UNIQVAR(strt)), slicePtr(name, UNIQVAR(ed)), ((name)->count - UNIQVAR(ed)) * sizeof (name)->array[0]);\
   4039   }\
   4040   (name)->count -= UNIQVAR(ed) - UNIQVAR(strt);\
   4041   } while(0)
   4042 
   4043 /**
   4044  * append slice to slice name
   4045  * the data is copied
   4046  */
   4047 #define sliceVAppend(name, slice) do {\
   4048   var UNIQVAR(vec) = slice;\
   4049   if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
   4050     sliceResize(name, (name)->count + (UNIQVAR(vec))->count);\
   4051     memmove((name)->array + (name)->count, (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
   4052     (name)->count += (UNIQVAR(vec))->count;\
   4053   }\
   4054   } while(0)
   4055 
   4056 /**
   4057  * append array to slice
   4058  * the data is copied
   4059  */
   4060 #define sliceAppendFrom(name, array, countInt) do {\
   4061   var UNIQVAR(c) = countInt;\
   4062   var UNIQVAR(a) = array;\
   4063   if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
   4064     sliceResize(name, (name)->count + UNIQVAR(c));\
   4065     memmove((name)->array + (name)->count, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
   4066     (name)->count += UNIQVAR(c);\
   4067   }\
   4068   } while(0)
   4069 
   4070 /**
   4071  * prepend slice to slice name
   4072  * the data in slice name is moved and
   4073  * the data in slice is copied to slice name
   4074  */
   4075 #define sliceVPrepend(name, slice) do {\
   4076   var UNIQVAR(vec) = slice;\
   4077   if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
   4078     sliceResize(name, (name)->count + (UNIQVAR(vec))->count);\
   4079     memmove((name)->array + (UNIQVAR(vec))->count, (name)->array, (name)->count * sizeof (name)->array[0]);\
   4080     memmove((name)->array, (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
   4081     (name)->count += (UNIQVAR(vec))->count;\
   4082   }\
   4083   } while(0)
   4084 
   4085 /**
   4086  * prepend array to slice
   4087  * the data in slice is moved and
   4088  * the data in array is copied to slice
   4089  */
   4090 #define slicePrependFrom(name, array, countInt) do {\
   4091   var UNIQVAR(c) = countInt;\
   4092   var UNIQVAR(a) = array;\
   4093   if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
   4094     sliceResize(name, (name)->count + UNIQVAR(c));\
   4095     memmove((name)->array + UNIQVAR(c), (name)->array, (name)->count * sizeof (name)->array[0]);\
   4096     memmove((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
   4097     (name)->count += UNIQVAR(c);\
   4098   }\
   4099   } while(0);
   4100 
   4101 /**
   4102  * insert slice at position index
   4103  * the data in slice name is moved and
   4104  * the data in slice is copied to slice name
   4105  */
   4106 #define sliceInsert(name, index, slice) do {\
   4107   var UNIQVAR(idx) = index;\
   4108   var UNIQVAR(vec) = slice;\
   4109   if (UNIQVAR(idx) == (name)->count) {\
   4110     sliceAppend(name, UNIQVAR(vec));\
   4111   }\
   4112   else if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
   4113     sliceResize(name, (name)->count + (UNIQVAR(vec))->count);\
   4114     memmove((name)->array + UNIQVAR(idx) + (UNIQVAR(vec))->count, (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
   4115     memmove((name)->array + UNIQVAR(idx), (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
   4116     (name)->count += (UNIQVAR(vec))->count;\
   4117   }\
   4118   } while(0)
   4119 
   4120 /**
   4121  * insert array at position index
   4122  * the data in slice is moved and
   4123  * the data in array is copied to slice
   4124  */
   4125 #define sliceInsertFrom(name, index, array, countInt) do {\
   4126   var UNIQVAR(idx) = index;\
   4127   var UNIQVAR(c)   = countInt;\
   4128   var UNIQVAR(a)   = array;\
   4129   if (UNIQVAR(idx) == (name)->count) {\
   4130     sliceAppendFrom(name, UNIQVAR(a), UNIQVAR(c));\
   4131   }\
   4132   else if (sizeof((name)->array[0]) == sizeof(UNIQVAR(a)[0])) {\
   4133     sliceResize(name, (name)->count + UNIQVAR(c));\
   4134     memmove((name)->array + UNIQVAR(idx) + UNIQVAR(c), (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
   4135     memmove((name)->array + UNIQVAR(idx), UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
   4136     (name)->count += UNIQVAR(c);\
   4137   }\
   4138   } while(0)
   4139 
   4140 /**
   4141  * slice slice, keep only elements between start and end
   4142  * start must be between 0 and last index
   4143  * end must be between 1 and count
   4144  * the slice is returned
   4145  */
   4146 #define sliceSlice(name, start, end) ({\
   4147   var UNIQVAR(strt) = start;\
   4148   var UNIQVAR(ed)   = end;\
   4149   if (UNIQVAR(strt))\
   4150     memmove((name)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
   4151   (name)->count = UNIQVAR(ed) - UNIQVAR(strt);\
   4152   name;\
   4153   })
   4154 
   4155 /**
   4156  * copy slice elements between start and end to a new slice
   4157  * start must be between 0 and last index
   4158  * end must be between 1 and count
   4159  * the new slice is returned and must be freed with sliceTerminate
   4160  */
   4161 #define sliceCopy(name, start, end) ({\
   4162   var UNIQVAR(strt) = start;\
   4163   var UNIQVAR(ed)   = end;\
   4164   createAllocateSliceCount(typeof(*(name)),UNIQVAR(r), UNIQVAR(ed) - UNIQVAR(strt));\
   4165   memmove(UNIQVAR(r)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
   4166   UNIQVAR(r)->count = UNIQVAR(ed) - UNIQVAR(strt);\
   4167   UNIQVAR(r);\
   4168   })
   4169 
   4170 /**
   4171  * copy slice elements between start and end to the dest slice
   4172  * start must be between 0 and last index
   4173  * end must be between 1 and count
   4174  */
   4175 #define sliceBCopy(name, dest, start, end) do{\
   4176   if (sizeof((name)->array[0]) == sizeof((dest)->array[0])) {\
   4177     var UNIQVAR(strt) = start;\
   4178     var UNIQVAR(ed)   = end;\
   4179     sliceResize(dest, UNIQVAR(ed) - UNIQVAR(strt));\
   4180     memmove((dest)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
   4181     (dest)->count = UNIQVAR(ed) - UNIQVAR(strt);\
   4182   }\
   4183   } while(0)
   4184 
   4185 /**
   4186  * sort the slice
   4187  * the compareFunction must prototype of type:
   4188  * int cmp(const void * a, const void * b);
   4189  * the results of the compareFunction should be:
   4190  * <0 when a < b
   4191  * 0  when a = b
   4192  * >0 when a > b
   4193  */
   4194 #define sliceSort(name, compareFunction) do{ \
   4195   qsort((name)->array, sizeof (name)->array[0], compareFunction);\
   4196   } while(0)
   4197 
   4198 /**
   4199  * return true when slice name is equal to slice
   4200  * eqFunction should return true when the elements are equal
   4201  * eqFunction can be either a macro or a function
   4202  */
   4203 #define sliceEq(name, slice, eqFunction) ({\
   4204     var UNIQVAR(vec) = slice;\
   4205     bool UNIQVAR(r)  = true;\
   4206     if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0]) and (name)->count == UNIQVAR(vec)->count) {\
   4207       forEachV(name, UNIQVAR(idx)) {\
   4208         if (not eqFunction(sliceAt(name,UNIQVAR(idx)), sliceAt(UNIQVAR(vec),UNIQVAR(idx)))) {\
   4209           UNIQVAR(r) = false;\
   4210           break;\
   4211         }\
   4212       }\
   4213     }\
   4214     else UNIQVAR(r) = false;\
   4215     UNIQVAR(r);\
   4216   })
   4217 
   4218 /**
   4219  * return true when slice has value
   4220  * eqFunction should return true when the elements are equal
   4221  * eqFunction can be either a macro or a function
   4222  */
   4223 #define sliceHas(name, value, eqFunction) ({\
   4224     var UNIQVAR(v)  = value;\
   4225     bool UNIQVAR(r) = false;\
   4226     forEachV(name, UNIQVAR(idx)) {\
   4227         if (eqFunction(sliceAt(name,UNIQVAR(idx)), UNIQVAR(v))) {\
   4228           UNIQVAR(r) = true;\
   4229           break;\
   4230         }\
   4231     }\
   4232     UNIQVAR(r);\
   4233   })
   4234 
   4235 /**
   4236  * return index (ssize_t) of value in slice
   4237  * eqFunction should return true when the elements are equal
   4238  * eqFunction can be either a macro or a function
   4239  *
   4240  * return value is -1 when value is not found
   4241  */
   4242 #define sliceIndexOf(name, value, eqFunction) ({\
   4243     var UNIQVAR(v)     = value;\
   4244     ssize_t UNIQVAR(r) = -1;\
   4245     forEachV(name, UNIQVAR(idx)) {\
   4246         if (eqFunction(sliceAt(name,UNIQVAR(idx)), UNIQVAR(v))) {\
   4247           UNIQVAR(r) = UNIQVAR(idx);\
   4248           break;\
   4249         }\
   4250     }\
   4251     UNIQVAR(r);\
   4252   })
   4253 
   4254 /**
   4255  * binary search value in slice
   4256  *
   4257  * efficiently finds the index of value in slice
   4258  * the slice has to be sorted before calling sliceBinarySearch
   4259  *
   4260  * less is a macro taking an index and the search value returning 1 when sliceAt(name,index) is less than value:
   4261  * #define less(index, value) sliceAt(name, index) < value
   4262  *
   4263  * equal is a macro returning 1 when sliceAt(name,index) is equal to value:
   4264  * #define equal(index, value) sliceAt(name,index) == value
   4265  *
   4266  * return value is -1 when value is not found
   4267  */
   4268 #define sliceBinarySearch(name, value, less, equal) ({\
   4269     var UNIQVAR(v) = value;\
   4270     ssize_t UNIQVAR(r);\
   4271     BSEARCH(UNIQVAR(r), UNIQVAR(v), (name)->count, less, equal);\
   4272     UNIQVAR(r);\
   4273   })
   4274 
   4275 /**
   4276  * Uniquify elements in slice
   4277  * each elements are unique in the slice
   4278  *
   4279  * eqFunction should return true when the elements are equal
   4280  * eqFunction can be either a macro or a function
   4281  */
   4282 #define sliceUniq(name, eqFunction) do{\
   4283   if ((name)->count > 1) {\
   4284     /* more than 1 element in slice, it is possible to have non unique elements */\
   4285     /* where to copy unique elements */\
   4286     size_t UNIQVAR(addIdx) = 0;\
   4287     /* scan all elements */\
   4288     forEachV(name, UNIQVAR(idx)) {\
   4289       /* whether [idx+1, count] has an element equal the one at idx */\
   4290       bool UNIQVAR(has) = false;\
   4291       /* last element is always unique */\
   4292       if (UNIQVAR(idx) < (name)->count) {\
   4293         rangeFrom(UNIQVAR(i), UNIQVAR(idx)+1, (name)->count) {\
   4294           if (eqFunction(sliceAt(name,UNIQVAR(i)), sliceAt(name,UNIQVAR(idx)))) {\
   4295             UNIQVAR(r) = true;\
   4296             break;\
   4297           }\
   4298         }\
   4299       }\
   4300       /* if [idx+1, count] doesnt have an equal element then the element at idx is unique */\
   4301       if (not UNIQVAR(has)) {\
   4302         /* copy element to addIdx when addIdx < idx */\
   4303         /* when addIdx == idx there is no need to copy the element */\
   4304         if (UNIQVAR(addIdx) < UNIQVAR(idx)) {\
   4305           sliceAt(name,UNIQVAR(addIdx)) = sliceAt(name,UNIQVAR(idx));\
   4306         }\
   4307         UNIQVAR(addIdx)++;\
   4308       }\
   4309     }\
   4310     /* set new count */\
   4311     (name)->count = UNIQVAR(addIdx);\
   4312   }\
   4313   } while(0)
   4314 
   4315 /*
   4316  * end slice
   4317  */
   4318 
   4319 /**
   4320  * staticSlice - static array with element count
   4321  *
   4322  * pushing elements into the array increases the element count
   4323  * poping elements only decreases the element count
   4324  *
   4325  * no sanity checks are done
   4326  *
   4327  * the prefix is staticSlice
   4328  *
   4329  * Usage:
   4330  *
   4331  * to declare a staticSlice:
   4332  *
   4333  * staticSliceT(typeName, type, 10);
   4334  *
   4335  * typeName slce;
   4336  *
   4337  * staticSliceInit(&slce);
   4338  *
   4339  * staticSliceAppend(&slce, value);
   4340  *
   4341  * // get an element
   4342  * int a                = staticSliceAt(&slce, 0);
   4343  *
   4344  * set
   4345  * staticSliceAt(&slce, 1) = 3;
   4346  *
   4347  * staticSliceFree(&slce);
   4348  *
   4349  * StaticSlice variables:
   4350  * slce.array:    elements
   4351  * slce.count:    current element count
   4352  *
   4353  * Note: some functions are macros to be able to have structs as element and
   4354  *       access the struct members directly, for example:
   4355  *         staticSliceLast(chan).a = 0;
   4356  */
   4357 
   4358 /**
   4359  * declares type for staticSlice
   4360  *
   4361  * \param
   4362  * typeName staticSlice type name
   4363  * \param
   4364  * element type of elements (int, struct, pointer...)
   4365  * \param
   4366  * MAXCOUNT array/ring buffer size
   4367  */
   4368 #define staticSliceT(typeName, elementType, MAXCOUNT)\
   4369   typedef struct {\
   4370     size_t count;\
   4371     elementType array[MAXCOUNT];\
   4372   } typeName
   4373 
   4374 #define createStaticSlice(typeName, name) ;typeName name; staticSliceInit(&name)
   4375 
   4376 /**
   4377  * initialize empty staticSlice
   4378  *
   4379  * \param
   4380  * name variable name for staticSlice
   4381  */
   4382 #define staticSliceInit(name) do{\
   4383     (name)->count    = 0;\
   4384   } while(0)
   4385 
   4386 /**
   4387  * element type in slice
   4388  */
   4389 #define staticSliceElemType(name) typeof((name)->array[0])
   4390 
   4391 /**
   4392  * element pointer type in slice
   4393  */
   4394 #define staticSliceElemPtrType(name) typeof(&(name)->array[0])
   4395 
   4396 /**
   4397  * duplicate staticSlice to already declared dest staticSlice
   4398  */
   4399 #define staticSliceBDup(name, dest) do{\
   4400   var UNIQVAR(dst) = dest;\
   4401   if ((name)->count <= ARRAY_SIZE(UNIQVAR(dst)->array)) {\
   4402     memcpy(UNIQVAR(dst)->array, (name)->array, (name)->count * sizeof (name)->array[0]);\
   4403     UNIQVAR(dst)->count = (name)->count;\
   4404   }\
   4405   } while(0)
   4406 
   4407 
   4408 /**
   4409  * direct access to underlying array
   4410  */
   4411 #define staticSliceData sliceData
   4412 
   4413 /**
   4414  * copy data from array to staticSlice
   4415  */
   4416 #define staticSliceFrom(name, arrayIn, countInt) do{\
   4417     var UNIQVAR(c) = countInt;\
   4418     var UNIQVAR(a) = arrayIn;\
   4419     if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a))) /* slice compatibility and UNIQVAR(c) <= ARRAY_SIZE((name)->array)*/) {\
   4420       memcpy((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof UNIQVAR(a)[0]);\
   4421       (name)->count = UNIQVAR(c);\
   4422     }\
   4423   } while(0)
   4424 
   4425 
   4426 /**
   4427  * set 0 in staticSlice elements
   4428  * count is unchanged
   4429  */
   4430 #define staticSliceClear(name) memset((name)->array, 0, (name)->count * sizeof (name)->array[0])
   4431 
   4432 #define staticSliceClearRange(name, start, end) memset((name)->array + start, 0, (end-start) * sizeof (name)->array[0])
   4433 
   4434 /**
   4435  * Empty staticSlice
   4436  * Set count to 0
   4437  * Allocated buffers in the staticSlice must be freed before running staticSliceEmpty
   4438  */
   4439 #define staticSliceEmpty sliceEmpty
   4440 
   4441 /**
   4442  * is staticSlice Empty
   4443  */
   4444 #define staticSliceIsEmpty(name) ((name)->count == 0)
   4445 
   4446 /**
   4447  * return element count
   4448  */
   4449 #define staticSliceCount sliceCount
   4450 
   4451 /**
   4452  * size of staticSlice element
   4453  */
   4454 #define staticSliceElemSize sliceElemSize
   4455 
   4456 /**
   4457  * clear (set 0) in element at index
   4458  */
   4459 #define staticSliceClearElem sliceClearElem
   4460 
   4461 /**
   4462  * push element and expand the staticSlice
   4463  * no data (random) is set in the new element
   4464  *
   4465  * \param
   4466  * name staticSlice
   4467  */
   4468 #define staticSlicePush(name)  (name)->count++
   4469 
   4470 /**
   4471  * append element and expand the staticSlice
   4472  *
   4473  * \param
   4474  * name staticSlice
   4475  * \param
   4476  * v element to push
   4477  */
   4478 #define staticSliceAppend(name, v) do{\
   4479     staticSlicePush(name);\
   4480     staticSliceLast(name) = v;\
   4481   } while(0)
   4482 
   4483 
   4484 /**
   4485  * push element and expand the staticSlice
   4486  * the new element is cleared
   4487  *
   4488  * \param
   4489  * name staticSlice
   4490  */
   4491 #define staticSliceClearPush(name) do{\
   4492     staticSlicePush(name);\
   4493     staticSliceClearElem(name, (name)->count - 1);\
   4494   } while(0)
   4495 
   4496 /**
   4497  * pop element
   4498  * the element count is decreased
   4499  *
   4500  * NOTE: using comma operator to avoid warning
   4501  * warning: operation on ‘b.head’ may be undefined [-Wsequence-point]
   4502  *
   4503  *
   4504  * \param
   4505  * name staticSlice
   4506  */
   4507 #define staticSlicePop slicePop
   4508 
   4509 /**
   4510  * delete the last element
   4511  * useful for avoiding warning: right-hand operand of comma expression has no effect
   4512  * when the poped value is not used
   4513  */
   4514 #define staticSliceDelLast sliceDelLast
   4515 
   4516 /**
   4517  * get / set element at index
   4518  *
   4519  * \param
   4520  * name staticSlice
   4521  * \param
   4522  * index index in array
   4523  */
   4524 #define staticSliceAt sliceAt
   4525 
   4526 /**
   4527  * get pointer to element at index
   4528  *
   4529  * \param
   4530  * name staticSlice
   4531  * \param
   4532  * index index in array
   4533  */
   4534 #define staticSlicePtr slicePtr
   4535 
   4536 /**
   4537  * last element
   4538  *
   4539  * \param
   4540  * name staticSlice
   4541  */
   4542 #define staticSliceLast sliceLast
   4543 
   4544 /**
   4545  * pointer to last element
   4546  *
   4547  * \param
   4548  * name staticSlice
   4549  */
   4550 #define staticSliceLastPtr sliceLastPtr
   4551 
   4552 /**
   4553  * index of last element
   4554  */
   4555 #define staticSliceLastIndex sliceLastIndex
   4556 
   4557 
   4558 /**
   4559  * first element
   4560  *
   4561  * \param
   4562  * name staticSlice
   4563  */
   4564 #define staticSliceFirst sliceFirst
   4565 
   4566 
   4567 /**
   4568  * write the staticSlice content to filename file
   4569  * No NULL checks are done on the parameters
   4570  *
   4571  * \param
   4572  *    filename file name string
   4573  */
   4574 #define staticSliceWriteFilename sliceWriteFilename
   4575 
   4576 /**
   4577  * write the staticSlice content to disk
   4578  * No NULL checks are done on the parameters
   4579  *
   4580  * \param
   4581  *    file already opened file
   4582  */
   4583 #define staticSliceWrite sliceWrite
   4584 
   4585 /**
   4586  * read a staticSlice from filename file
   4587  * No NULL checks are done on the parameters
   4588  *
   4589  * \param
   4590  * filename file name string
   4591  */
   4592 #define staticSliceReadFilename(name, filename) do {\
   4593     if (fileExists(filename)) {\
   4594       size_t UNIQVAR(sz) = fileSize(filename);\
   4595       FILE *UNIQVAR(f) = fopen(filename, "r");\
   4596       if (UNIQVAR(f)) {\
   4597         range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
   4598           staticSlicePush(name);\
   4599           fread(staticSliceLastPtr(name), 1, sizeof((name)->array[0]), UNIQVAR(f));\
   4600         }\
   4601         fclose(UNIQVAR(f));\
   4602       }\
   4603     }\
   4604   } while(0)
   4605 
   4606 /**
   4607  * read a staticSlice from disk
   4608  * No NULL checks are done on the parameters
   4609  *
   4610  * \param
   4611  *    file already opened file
   4612  */
   4613 #define staticSliceRead(name, file) do {\
   4614     fseek(file, 0 , SEEK_END);\
   4615     size_t UNIQVAR(sz) = ftell(file);\
   4616     fseek(file, 0 , SEEK_SET);\
   4617     range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
   4618       staticSlicePush(name);\
   4619       fread(staticSliceLastPtr(name), 1, sizeof((name)->array[0]), file);\
   4620     }\
   4621   } while(0)
   4622 
   4623 
   4624 /**
   4625  * loop index on staticSlice elements
   4626  *
   4627  * For example:
   4628  * forEachV(vec, i) {
   4629  *   staticSliceAt(vec, i) = 0;
   4630  * }
   4631  */
   4632 #define forEachSSc forEachSc
   4633 
   4634 /**
   4635  * loop on slice elements
   4636  * element is a pointer to a value in the array
   4637  *
   4638  * staticSliceForEach(&slc, e) {
   4639  *    e->x = 0;
   4640  * }
   4641  */
   4642 #define staticSliceForEach(name, element) \
   4643   ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
   4644   for (staticSliceElemPtrType(name) element = staticSlicePtr(name, 0) ; UNIQVAR(libsheepyInternalIndex) < (name)->count ; UNIQVAR(libsheepyInternalIndex)++, element = staticSlicePtr(name, UNIQVAR(libsheepyInternalIndex)))
   4645 
   4646 /**
   4647  * enumerate slice elements
   4648  * index is the position of the element in the array
   4649  * index is declared as size_t and is available after the loop
   4650  * element is a pointer to a value in the array
   4651  *
   4652  * sliceEnumerate(&slc, i, e) {
   4653  *    e->x = 0;
   4654  *    printf("sliceEnumerate %d\n", i);
   4655  * }
   4656  */
   4657 #define staticSliceEnumerate(name, index, element) \
   4658   ; size_t index = 0 ; \
   4659   for (staticSliceElemPtrType(name) element = staticSlicePtr(name, 0) ; index < (name)->count ; index++, element = staticSlicePtr(name, index))
   4660 
   4661 /**
   4662  * insert an element at index
   4663  * the data is moved to create space for the new element
   4664  * to set data at the new element, use staticSliceAt(name, index) = value;
   4665  */
   4666 #define staticSliceInject(name, index) do {\
   4667   var UNIQVAR(idx) = index;\
   4668   staticSlicePush(name);\
   4669   memmove(staticSlicePtr(name, UNIQVAR(idx) +1), staticSlicePtr(name, UNIQVAR(idx)), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
   4670   } while(0)
   4671 
   4672 /**
   4673  * prepend element
   4674  *
   4675  * \param
   4676  * name staticSlice
   4677  * \param
   4678  * v element to prepend
   4679  */
   4680 #define staticSlicePrepend(name, v) do {\
   4681     staticSliceInject(name, 0);\
   4682     staticSliceAt(name, 0) = v;\
   4683   } while(0)
   4684 
   4685 /**
   4686  * dequeue element
   4687  *
   4688  * \param
   4689  * name staticSlice
   4690  */
   4691 #define staticSliceDequeue sliceDequeue
   4692 
   4693 /**
   4694  * delete first element in staticSlice
   4695  * the data is moved when count > 1
   4696  */
   4697 #define staticSliceDelFirst sliceDelFirst
   4698 
   4699 
   4700 /**
   4701  * delete an element in staticSlice
   4702  * the data is moved when index < (count-1)
   4703  * when index = count -1, the last element is deleted and no data is moved
   4704  */
   4705 #define staticSliceDelElem sliceDelElem
   4706 
   4707 /**
   4708  * delete range in staticSlice
   4709  * start must be between 0 and last index
   4710  * end must be between 1 and count
   4711  */
   4712 #define staticSliceDel sliceDel
   4713 
   4714 /**
   4715  * append staticSlice to staticSlice name
   4716  * the data is copied
   4717  */
   4718 #define staticSliceVAppend(name, staticSlice) do {\
   4719   var UNIQVAR(vec) = staticSlice;\
   4720   if (sizeof((name)->array[0]) == sizeof(UNIQVAR(vec)->array[0]) /* slice compatibility and ((name)->count + UNIQVAR(vec)->count) <= ARRAY_SIZE((name)->array)*/) {\
   4721     memcpy((name)->array + (name)->count, UNIQVAR(vec)->array, UNIQVAR(vec)->count * sizeof (name)->array[0]);\
   4722     (name)->count += UNIQVAR(vec)->count;\
   4723   }\
   4724   } while(0)
   4725 
   4726 /**
   4727  * append array to staticSlice
   4728  * the data is copied
   4729  */
   4730 #define staticSliceAppendFrom(name, array, countInt) do {\
   4731   var UNIQVAR(c) = countInt;\
   4732   var UNIQVAR(a) = array;\
   4733   if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a))) /* slice compatibility and ((name)->count + UNIQVAR(c)) <= ARRAY_SIZE((name)->array)*/) {\
   4734     memcpy((name)->array + (name)->count, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
   4735     (name)->count += UNIQVAR(c);\
   4736   }\
   4737   } while(0)
   4738 
   4739 /**
   4740  * prepend staticSlice to staticSlice name
   4741  * the data in staticSlice name is moved and
   4742  * the data in staticSlice is copied to staticSlice name
   4743  */
   4744 #define staticSliceVPrepend(name, staticSlice) do {\
   4745   var UNIQVAR(vec) = staticSlice;\
   4746   if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0]) /* slice compatibility and ((name)->count + UNIQVAR(vec)->count) <= ARRAY_SIZE((name)->array)*/) {\
   4747     memmove((name)->array + (UNIQVAR(vec))->count, (name)->array, (name)->count * sizeof (name)->array[0]);\
   4748     memcpy((name)->array, (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
   4749     (name)->count += (UNIQVAR(vec))->count;\
   4750   }\
   4751   } while(0)
   4752 
   4753 /**
   4754  * prepend array to staticSlice
   4755  * the data in staticSlice is moved and
   4756  * the data in array is copied to staticSlice
   4757  */
   4758 #define staticSlicePrependFrom(name, array, countInt) do {\
   4759   var UNIQVAR(c) = countInt;\
   4760   var UNIQVAR(a) = array;\
   4761   if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a))) /* slice compatibility and ((name)->count + UNIQVAR(c)) <= ARRAY_SIZE((name)->array)*/) {\
   4762     staticSliceResize(name, (name)->count + UNIQVAR(c));\
   4763     memmove((name)->array + UNIQVAR(c), (name)->array, (name)->count * sizeof (name)->array[0]);\
   4764     memcpy((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
   4765     (name)->count += UNIQVAR(c);\
   4766   }\
   4767   } while(0);
   4768 
   4769 /**
   4770  * insert staticSlice at position index
   4771  * the data in staticSlice name is moved and
   4772  * the data in staticSlice is copied to staticSlice name
   4773  */
   4774 #define staticSliceInsert(name, index, staticSlice) do {\
   4775   var UNIQVAR(idx) = index;\
   4776   var UNIQVAR(vec) = staticSlice;\
   4777   if (UNIQVAR(idx) == (name)->count) {\
   4778     staticSliceAppend(name, UNIQVAR(vec));\
   4779   }\
   4780   else if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0]) /* slice compatibility and ((name)->count + UNIQVAR(vec)->count) <= ARRAY_SIZE((name)->array)*/) {\
   4781     memmove((name)->array + UNIQVAR(idx) + (UNIQVAR(vec))->count, (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
   4782     memcpy((name)->array + UNIQVAR(idx), (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
   4783     (name)->count += (UNIQVAR(vec))->count;\
   4784   }\
   4785   } while(0)
   4786 
   4787 /**
   4788  * insert array at position index
   4789  * the data in staticSlice is moved and
   4790  * the data in array is copied to staticSlice
   4791  */
   4792 #define staticSliceInsertFrom(name, index, array, countInt) do {\
   4793   var UNIQVAR(idx) = index;\
   4794   var UNIQVAR(c)   = countInt;\
   4795   var UNIQVAR(a)   = array;\
   4796   if (UNIQVAR(idx) == (name)->count) {\
   4797     staticSliceAppendFrom(name, UNIQVAR(a), UNIQVAR(c));\
   4798   }\
   4799   else if (sizeof((name)->array[0]) == sizeof(UNIQVAR(a)[0]) /* slice compatibility and ((name)->count + UNIQVAR(c)) <= ARRAY_SIZE((name)->array)*/) {\
   4800     memmove((name)->array + UNIQVAR(idx) + UNIQVAR(c), (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
   4801     memcpy((name)->array + UNIQVAR(idx), UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
   4802     (name)->count += UNIQVAR(c);\
   4803   }\
   4804   } while(0)
   4805 
   4806 /**
   4807  * staticSlice staticSlice, keep only elements between start and end
   4808  * start must be between 0 and last index
   4809  * end must be between 1 and count
   4810  * the staticSlice is returned
   4811  */
   4812 #define staticSliceSlice sliceSlice
   4813 
   4814 /**
   4815  * copy staticSlice elements between start and end to the dest staticSlice
   4816  * start must be between 0 and last index
   4817  * end must be between 1 and count
   4818  */
   4819 #define staticSliceBCopy(name, dest, start, end) do{\
   4820   if (sizeof((name)->array[0]) == sizeof((dest)->array[0]) /* slice compatibility and (UNIQVAR(ed) - UNIQVAR(strt)) <= ARRAY_SIZE((dest)->array)*/) {\
   4821     var UNIQVAR(strt) = start;\
   4822     var UNIQVAR(ed)   = end;\
   4823     staticSliceResize(dest, UNIQVAR(ed) - UNIQVAR(strt));\
   4824     memcpy((dest)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
   4825     (dest)->count = UNIQVAR(ed) - UNIQVAR(strt);\
   4826   }\
   4827   } while(0)
   4828 
   4829 /**
   4830  * sort the staticSlice
   4831  * the compareFunction must prototype of type:
   4832  * int cmp(const void * a, const void * b);
   4833  * the results of the compareFunction should be:
   4834  * <0 when a < b
   4835  * 0  when a = b
   4836  * >0 when a > b
   4837  */
   4838 #define staticSliceSort sliceSort
   4839 
   4840 /**
   4841  * return true when staticSlice name is equal to staticSlice
   4842  * eqFunction should return true when the elements are equal
   4843  * eqFunction can be either a macro or a function
   4844  */
   4845 #define staticSliceEq sliceEq
   4846 
   4847 /**
   4848  * return true when staticSlice has value
   4849  * eqFunction should return true when the elements are equal
   4850  * eqFunction can be either a macro or a function
   4851  */
   4852 #define staticSliceHas sliceHas
   4853 
   4854 /**
   4855  * return index (ssize_t) of value in staticSlice
   4856  * eqFunction should return true when the elements are equal
   4857  * eqFunction can be either a macro or a function
   4858  *
   4859  * return value is -1 when value is not found
   4860  */
   4861 #define staticSliceIndexOf sliceIndexOf
   4862 
   4863 /**
   4864  * binary search value in staticSlice
   4865  *
   4866  * efficiently finds the index of value in staticSlice
   4867  * the staticSlice has to be sorted before calling staticSliceBinarySearch
   4868  *
   4869  * less is a macro taking an index and the search value returning 1 when staticSliceAt(name,index) is less than value:
   4870  * #define less(index, value) staticSliceAt(name, index) < value
   4871  *
   4872  * equal is a macro returning 1 when staticSliceAt(name,index) is equal to value:
   4873  * #define equal(index, value) staticSliceAt(name,index) == value
   4874  *
   4875  * return value is -1 when value is not found
   4876  */
   4877 #define staticSliceBinarySearch sliceBinarySearch
   4878 
   4879 /**
   4880  * Uniquify elements in staticSlice
   4881  * each elements are unique in the staticSlice
   4882  *
   4883  * eqFunction should return true when the elements are equal
   4884  * eqFunction can be either a macro or a function
   4885  */
   4886 #define staticSliceUniq sliceUniq
   4887 
   4888 /*
   4889  * end staticSlice
   4890  */
   4891 
   4892 /**
   4893  * vector - dynamic array in one chunk of memory (similar to slab below)
   4894  *
   4895  * This is a simple dynamic array holding element count, maximum element count and the data
   4896  *
   4897  * vector supports shrinking through vectorResize
   4898  *
   4899  * this type of array has a dynamic element count
   4900  * pushing elements into the array increases the element count
   4901  * poping elements only decreases the element count, call vectorFit to resize the vector
   4902  *
   4903  * no sanity checks are done
   4904  *
   4905  * the prefix is vector
   4906  *
   4907  * Usage:
   4908  *
   4909  * to declare a vector:
   4910  *
   4911  * vectorT(typeName, type);
   4912  *
   4913  * typeName vectr;
   4914  *
   4915  * vectorInit(&vectr);
   4916  * or
   4917  * vectorInitCount(&vectr, 17);
   4918  *
   4919  * vectorAppend(&vectr, value);
   4920  *
   4921  * // get an element
   4922  * int a                = vectorAt(&vectr, 0);
   4923  *
   4924  * set
   4925  * vectorAt(&vectr, 1) = 3;
   4926  *
   4927  * vectorFree(&vectr);
   4928  *
   4929  * Vector variables:
   4930  * vectr.array:    elements
   4931  * vectr.count:    current element count
   4932  * vectr.maxCount: maximum element count allowed
   4933  *
   4934  * Note: some functions are macros to be able to have structs as element and
   4935  *       access the struct members directly, for example:
   4936  *         vectorLast(chan).a = 0;
   4937  */
   4938 
   4939 /** number of elements added by vectorAlloc */
   4940 #define vectorSz 1
   4941 
   4942 /**
   4943  * declares type for vector
   4944  *
   4945  * \param
   4946  * typeName vector type name
   4947  * \param
   4948  * element type of elements (int, struct, pointer...)
   4949  */
   4950 #define vectorT(typeName, elementType)\
   4951   typedef struct {\
   4952     size_t count;\
   4953     size_t maxCount;\
   4954     elementType *array;\
   4955   } typeName
   4956 
   4957 
   4958 #define createVector(typeName, name) ;typeName name; vectorInit(&name)
   4959 
   4960 #define createVectorCount(typeName, name, count) ;typeName name; vectorInitCount(&name, count)
   4961 
   4962 #define createVectorClearCount(typeName, name, count) ;typeName name; vectorCalloc(&name, count)
   4963 
   4964 #define createAllocateVector(typeName, name) ;typeName *name = calloc(1, sizeof(typeName))
   4965 
   4966 #define createAllocateVectorCount(typeName, name, count) ;typeName *name = calloc(1, sizeof(typeName)); vectorInitCount(name, count)
   4967 
   4968 #define createAllocateVectorClearCount(typeName, name, count) ;typeName *name = calloc(1, sizeof(typeName)); vectorCalloc(name, count)
   4969 
   4970 #define vectorTerminate(name) if (name) vectorFree(name);free(name)
   4971 
   4972 /**
   4973  * initialize empty vector
   4974  *
   4975  * \param
   4976  * name variable name for vector
   4977  */
   4978 #define vectorInit(name) do{\
   4979     (name)->array    = NULL;\
   4980     (name)->count    = 0;\
   4981     (name)->maxCount = 0;\
   4982   } while(0)
   4983 
   4984 /**
   4985  * initialize vector and count
   4986  *
   4987  * \param
   4988  * name variable name for vector
   4989  * \param
   4990  * count initial element count for name type
   4991  */
   4992 #define vectorInitCount(name, countInt) do{\
   4993     var UNIQVAR(c)   = countInt;\
   4994     (name)->array    = malloc(UNIQVAR(c) * sizeof (name)->array[0]);\
   4995     (name)->count    = 0;\
   4996     (name)->maxCount = UNIQVAR(c);\
   4997   } while(0)
   4998 
   4999 /**
   5000  * initialize vector and count and set vector data to 0
   5001  *
   5002  * \param
   5003  * name variable name for vector
   5004  * \param
   5005  * count initial element count for name type
   5006  */
   5007 #define vectorCalloc(name, countInt) do{\
   5008     var UNIQVAR(c)   = countInt;\
   5009     (name)->array    = calloc(UNIQVAR(c), sizeof (name)->array[0]);\
   5010     (name)->count    = 0;\
   5011     (name)->maxCount = UNIQVAR(c);\
   5012   } while(0)
   5013 
   5014 /**
   5015  * resize vector (even empty vectors)
   5016  */
   5017 #define vectorResize(name, countInt) do{\
   5018   var UNIQVAR(c) = countInt;\
   5019   if ((name)->array) {\
   5020     /* realloc */\
   5021     (name)->array = realloc((name)->array, sizeof((name)->array[0]) * UNIQVAR(c));\
   5022   }\
   5023   else {\
   5024     /* was empty */\
   5025     (name)->array = malloc(sizeof((name)->array[0]) * UNIQVAR(c));\
   5026   }\
   5027   /* element count when shrinking */\
   5028   if (UNIQVAR(c) < (name)->count) (name)->count = UNIQVAR(c);\
   5029   (name)->maxCount = UNIQVAR(c);\
   5030   } while(0)
   5031 
   5032 /**
   5033  * resize vector and clear the new elements with memset
   5034  * even empty vectors can be resized and cleared
   5035  */
   5036 #define vectorClearResize(name, countInt) do{\
   5037   var UNIQVAR(c) = countInt;\
   5038   if ((name)->array) {\
   5039     /* realloc */\
   5040     (name)->array = realloc((name)->array, sizeof((name)->array[0]) * UNIQVAR(c));\
   5041     if ((name)->count < UNIQVAR(c)) {\
   5042       /* there are new elements */\
   5043       memset(&(name)->array[(name)->count], 0, (UNIQVAR(c) - (name)->count) * sizeof (name)->array[0]);\
   5044     }\
   5045   }\
   5046   else {\
   5047     /* was empty */\
   5048     (name)->array = calloc(UNIQVAR(c), sizeof((name)->array[0]));\
   5049   }\
   5050   /* element count when shrinking */\
   5051   if (UNIQVAR(c) < (name)->count) (name)->count = UNIQVAR(c);\
   5052   (name)->maxCount = UNIQVAR(c);\
   5053   } while(0)
   5054 
   5055 /**
   5056  * free the internal buffers
   5057  *
   5058  * \param
   5059  * name vector
   5060  */
   5061 #define vectorFree sliceFree
   5062 
   5063 /**
   5064  * element type in vector
   5065  */
   5066 #define vectorElemType(name) typeof((name)->array[0])
   5067 
   5068 /**
   5069  * element pointer type in vector
   5070  */
   5071 #define vectorElemPtrType(name) typeof(&(name)->array[0])
   5072 
   5073 /**
   5074  * duplicate vector
   5075  */
   5076 #define vectorDup(name) ({\
   5077     typeof(*(name)) dest;\
   5078     vectorInitCount(dest, (name)->count);\
   5079     if ((name)->array) {\
   5080       memcpy(dest->array, (name)->array, (name)->count * sizeof (name)->array[0]);\
   5081       dest->count = (name)->count;\
   5082     }\
   5083     /* return */ dest;\
   5084   })
   5085 /**
   5086  * declare dest vector and duplicate vector
   5087  */
   5088 #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;}
   5089 
   5090 /**
   5091  * duplicate vector to already declared dest vector
   5092  */
   5093 #define vectorBDup(name, dest) do{\
   5094   var UNIQVAR(dst) = dest;\
   5095   vectorResize(UNIQVAR(dst), (name)->count);\
   5096   if ((name)->array) {\
   5097     memcpy(UNIQVAR(dst)->array, (name)->array, (name)->count * sizeof (name)->array[0]);\
   5098     dest->count = (name)->count;\
   5099   }\
   5100   } while(0)
   5101 
   5102 /**
   5103  * direct access to underlying array
   5104  */
   5105 #define vectorData sliceData
   5106 
   5107 /**
   5108  * copy data from array to vector
   5109  */
   5110 #define vectorFrom(name, array, countInt) do{\
   5111     var UNIQVAR(c) = countInt;\
   5112     var UNIQVAR(a) = array;\
   5113     if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
   5114       if (UNIQVAR(c) > (name)->maxCount)\
   5115         vectorResize(name, UNIQVAR(c));\
   5116       memcpy((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof UNIQVAR(a)[0]);\
   5117       (name)->count = UNIQVAR(c);\
   5118     }\
   5119   } while(0)
   5120 
   5121 /**
   5122  * set 0 in vector elements
   5123  * count is unchanged
   5124  */
   5125 #define vectorClear sliceClear
   5126 
   5127 #define vectorClearRange sliceClearRange
   5128 
   5129 /**
   5130  * Empty vector
   5131  * Set count to 0
   5132  * Allocated buffers in the vector must be freed before running vectorEmpty
   5133  */
   5134 #define vectorEmpty sliceEmpty
   5135 
   5136 /**
   5137  * is vector Empty
   5138  */
   5139 #define vectorIsEmpty sliceIsEmpty
   5140 
   5141 /**
   5142  * resize vector from maxCount to count
   5143  */
   5144 #define vectorFit(name) do{\
   5145     if ((name)->maxCount > (name)->count) {\
   5146       vectorResize(name, (name)->count);\
   5147     }\
   5148   } while(0)
   5149 
   5150 /**
   5151  * return element count
   5152  */
   5153 #define vectorCount sliceCount
   5154 
   5155 /**
   5156  * return max element count
   5157  */
   5158 #define vectorMaxCount(name) (name)->maxCount
   5159 
   5160 /**
   5161  * size of vector element
   5162  */
   5163 #define vectorElemSize sliceElemSize
   5164 
   5165 /**
   5166  * allocate an element
   5167  * only when the vector is full
   5168  */
   5169 #define vectorAlloc(name) do{\
   5170     if (!(name)->array) {\
   5171       (name)->array    = malloc(vectorSz * sizeof (name)->array[0]);\
   5172       (name)->maxCount = vectorSz;\
   5173     }\
   5174     else if ((name)->count == (name)->maxCount) {\
   5175       (name)->maxCount += vectorSz;\
   5176       (name)->array     = realloc((name)->array, (name)->maxCount * sizeof (name)->array[0]);\
   5177     }\
   5178   } while(0)
   5179 
   5180 /**
   5181  * clear (set 0) in element at index
   5182  */
   5183 #define vectorClearElem sliceClearElem
   5184 
   5185 /**
   5186  * push element and expand the vector
   5187  * no data (random) is set in the new element
   5188  *
   5189  * \param
   5190  * name vector
   5191  */
   5192 #define vectorPush(name) do {\
   5193     vectorAlloc(name);\
   5194     (name)->count++;\
   5195   } while(0)
   5196 
   5197 /**
   5198  * append element and expand the vector
   5199  *
   5200  * \param
   5201  * name vector
   5202  * \param
   5203  * v element to push
   5204  */
   5205 #define vectorAppend(name, v) do{\
   5206     vectorPush(name);\
   5207     vectorLast(name) = v;\
   5208   } while(0)
   5209 
   5210 
   5211 /**
   5212  * push element and expand the vector
   5213  * the new element is cleared
   5214  *
   5215  * \param
   5216  * name vector
   5217  */
   5218 #define vectorClearPush(name) do{\
   5219     vectorPush(name);\
   5220     vectorClearElem(name, (name)->count - 1);\
   5221   } while(0)
   5222 
   5223 /**
   5224  * pop element
   5225  * the element count is decreased
   5226  *
   5227  * NOTE: using comma operator to avoid warning
   5228  * warning: operation on ‘b.head’ may be undefined [-Wsequence-point]
   5229  *
   5230  *
   5231  * \param
   5232  * name vector
   5233  */
   5234 #define vectorPop slicePop
   5235 
   5236 /**
   5237  * delete the last element
   5238  * useful for avoiding warning: right-hand operand of comma expression has no effect
   5239  * when the poped value is not used
   5240  */
   5241 #define vectorDelLast sliceDelLast
   5242 
   5243 /**
   5244  * push multiple elements at once
   5245  *
   5246  * \param
   5247  * name vector
   5248  * \param
   5249  * countp number of elements to add
   5250  */
   5251 #define vectorPushCount(name, countp) procbegin\
   5252     u32 UNIQVAR(count) = countp;\
   5253     if (((name)->count + UNIQVAR(count)) > (name)->maxCount) {\
   5254             (name)->maxCount += UNIQVAR(count);\
   5255             (name)->array     = realloc((name)->array, (name)->maxCount * sizeof (name)->array[0]);\
   5256           }\
   5257     (name)->count += UNIQVAR(count);\
   5258   procend
   5259 
   5260 
   5261 /**
   5262  * set value at index and clearResize vector when index is outside vector maxCount
   5263  */
   5264 #define vectorSet(name, index, v) do{\
   5265     var UNIQVAR(idx) = index;\
   5266     if (UNIQVAR(idx) >= (name)->count) {\
   5267       /* clear and resize */\
   5268       vectorClearResize(name, UNIQVAR(idx)+1);\
   5269     }\
   5270     vectorAt(name, UNIQVAR(idx)) = v;\
   5271   } while(0)
   5272 
   5273 /**
   5274  * get / set element at index
   5275  *
   5276  * \param
   5277  * name vector
   5278  * \param
   5279  * index index in array
   5280  */
   5281 #define vectorAt sliceAt
   5282 
   5283 /**
   5284  * get pointer to element at index
   5285  *
   5286  * \param
   5287  * name vector
   5288  * \param
   5289  * index index in array
   5290  */
   5291 #define vectorPtr slicePtr
   5292 
   5293 /**
   5294  * last element
   5295  *
   5296  * \param
   5297  * name vector
   5298  */
   5299 #define vectorLast sliceLast
   5300 
   5301 /**
   5302  * pointer to last element
   5303  *
   5304  * \param
   5305  * name vector
   5306  */
   5307 #define vectorLastPtr sliceLastPtr
   5308 
   5309 /**
   5310  * index of last element
   5311  */
   5312 #define vectorLastIndex sliceLastIndex
   5313 
   5314 
   5315 /**
   5316  * first element
   5317  *
   5318  * \param
   5319  * name vector
   5320  */
   5321 #define vectorFirst sliceFirst
   5322 
   5323 
   5324 /**
   5325  * write the vector content to filename file
   5326  * No NULL checks are done on the parameters
   5327  *
   5328  * \param
   5329  *    filename file name string
   5330  */
   5331 #define vectorWriteFilename sliceWriteFilename
   5332 
   5333 /**
   5334  * write the vector content to disk
   5335  * No NULL checks are done on the parameters
   5336  *
   5337  * \param
   5338  *    file already opened file
   5339  */
   5340 #define vectorWrite sliceWrite
   5341 
   5342 /**
   5343  * read a vector from filename file
   5344  * No NULL checks are done on the parameters
   5345  *
   5346  * \param
   5347  * filename file name string
   5348  */
   5349 #define vectorReadFilename(name, filename) do {\
   5350     if (fileExists(filename)) {\
   5351       size_t UNIQVAR(sz) = fileSize(filename);\
   5352       FILE *UNIQVAR(f) = fopen(filename, "r");\
   5353       if (UNIQVAR(f)) {\
   5354         range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
   5355           vectorPush(name);\
   5356           fread(vectorLastPtr(name), 1, sizeof((name)->array[0]), UNIQVAR(f));\
   5357         }\
   5358         fclose(UNIQVAR(f));\
   5359       }\
   5360     }\
   5361   } while(0)
   5362 
   5363 /**
   5364  * read a vector from disk
   5365  * No NULL checks are done on the parameters
   5366  *
   5367  * \param
   5368  *    file already opened file
   5369  */
   5370 #define vectorRead(name, file) do {\
   5371     fseek(file, 0 , SEEK_END);\
   5372     size_t UNIQVAR(sz) = ftell(file);\
   5373     fseek(file, 0 , SEEK_SET);\
   5374     range(UNIQVAR(i), UNIQVAR(sz)/sizeof((name)->array[0])) {\
   5375       vectorPush(name);\
   5376       fread(vectorLastPtr(name), 1, sizeof((name)->array[0]), file);\
   5377     }\
   5378   } while(0)
   5379 
   5380 
   5381 /**
   5382  * loop index on vector elements
   5383  *
   5384  * For example:
   5385  * forEachV(vec, i) {
   5386  *   vectorAt(vec, i) = 0;
   5387  * }
   5388  */
   5389 #define forEachV forEachSc
   5390 
   5391 /**
   5392  * loop on vector elements
   5393  * element is a pointer to a value in the array
   5394  *
   5395  * vectorForEach(&slc, e) {
   5396  *    e->x = 0;
   5397  * }
   5398  */
   5399 #define vectorForEach(name, element) \
   5400   ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
   5401   for (vectorElemPtrType(name) element = vectorPtr(name, 0) ; UNIQVAR(libsheepyInternalIndex) < (name)->count ; UNIQVAR(libsheepyInternalIndex)++, element = vectorPtr(name, UNIQVAR(libsheepyInternalIndex)))
   5402 
   5403 /**
   5404  * enumerate vector elements
   5405  * index is the position of the element in the array
   5406  * index is declared as size_t and is available after the loop
   5407  * element is a pointer to a value in the array
   5408  *
   5409  * vectorEnumerate(&slc, i, e) {
   5410  *    e->x = 0;
   5411  *    printf("vectorEnumerate %d\n", i);
   5412  * }
   5413  */
   5414 #define vectorEnumerate(name, index, element) \
   5415   ; size_t index = 0 ; \
   5416   for (vectorElemPtrType(name) element = vectorPtr(name, 0) ; index < (name)->count ; index++, element = vectorPtr(name, index))
   5417 
   5418 /**
   5419  * insert an element at index
   5420  * the data is moved to create space for the new element
   5421  * to set data at the new element, use vectorAt(name, index) = value;
   5422  */
   5423 #define vectorInject(name, index) do {\
   5424   var UNIQVAR(idx) = index;\
   5425   vectorPush(name);\
   5426   memmove(vectorPtr(name, UNIQVAR(idx) +1), vectorPtr(name, UNIQVAR(idx)), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
   5427   } while(0)
   5428 
   5429 /**
   5430  * prepend element
   5431  *
   5432  * \param
   5433  * name vector
   5434  * \param
   5435  * v element to prepend
   5436  */
   5437 #define vectorPrepend(name, v) do {\
   5438     vectorInject(name, 0);\
   5439     vectorAt(name, 0) = v;\
   5440   } while(0)
   5441 
   5442 /**
   5443  * dequeue element
   5444  *
   5445  * \param
   5446  * name vector
   5447  */
   5448 #define vectorDequeue sliceDequeue
   5449 
   5450 /**
   5451  * delete first element in vector
   5452  * the data is moved when count > 1
   5453  */
   5454 #define vectorDelFirst sliceDelFirst
   5455 
   5456 
   5457 /**
   5458  * delete an element in vector
   5459  * the data is moved when index < (count-1)
   5460  * when index = count -1, the last element is deleted and no data is moved
   5461  */
   5462 #define vectorDelElem sliceDelElem
   5463 
   5464 /**
   5465  * delete range in vector
   5466  * start must be between 0 and last index
   5467  * end must be between 1 and count
   5468  */
   5469 #define vectorDel sliceDel
   5470 
   5471 /**
   5472  * append vector to vector name
   5473  * the data is copied
   5474  */
   5475 #define vectorVAppend(name, vector) do {\
   5476   var UNIQVAR(vec) = vector;\
   5477   if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
   5478     if (((name)->count + (UNIQVAR(vec))->count) > (name)->maxCount)\
   5479       vectorResize(name, (name)->count + (UNIQVAR(vec))->count);\
   5480     memcpy((name)->array + (name)->count, (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
   5481     (name)->count += (UNIQVAR(vec))->count;\
   5482   }\
   5483   } while(0)
   5484 
   5485 /**
   5486  * append array to vector
   5487  * the data is copied
   5488  */
   5489 #define vectorAppendFrom(name, array, countInt) do {\
   5490   var UNIQVAR(c) = countInt;\
   5491   var UNIQVAR(a) = array;\
   5492   if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
   5493     if (((name)->count + UNIQVAR(c)) > (name)->maxCount)\
   5494       vectorResize(name, (name)->count + UNIQVAR(c));\
   5495     memcpy((name)->array + (name)->count, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
   5496     (name)->count += UNIQVAR(c);\
   5497   }\
   5498   } while(0)
   5499 
   5500 /**
   5501  * prepend vector to vector name
   5502  * the data in vector name is moved and
   5503  * the data in vector is copied to vector name
   5504  */
   5505 #define vectorVPrepend(name, vector) do {\
   5506   var UNIQVAR(vec) = vector;\
   5507   if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
   5508     if (((name)->count + (UNIQVAR(vec))->count) > (name)->maxCount)\
   5509       vectorResize(name, (name)->count + (UNIQVAR(vec))->count);\
   5510     memmove((name)->array + (UNIQVAR(vec))->count, (name)->array, (name)->count * sizeof (name)->array[0]);\
   5511     memcpy((name)->array, (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
   5512     (name)->count += (UNIQVAR(vec))->count;\
   5513   }\
   5514   } while(0)
   5515 
   5516 /**
   5517  * prepend array to vector
   5518  * the data in vector is moved and
   5519  * the data in array is copied to vector
   5520  */
   5521 #define vectorPrependFrom(name, array, countInt) do {\
   5522   var UNIQVAR(c) = countInt;\
   5523   var UNIQVAR(a) = array;\
   5524   if (sizeof((name)->array[0]) == sizeof(*(UNIQVAR(a)))) {\
   5525     if (((name)->count + UNIQVAR(c)) > (name)->maxCount)\
   5526       vectorResize(name, (name)->count + UNIQVAR(c));\
   5527     memmove((name)->array + UNIQVAR(c), (name)->array, (name)->count * sizeof (name)->array[0]);\
   5528     memcpy((name)->array, UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
   5529     (name)->count += UNIQVAR(c);\
   5530   }\
   5531   } while(0);
   5532 
   5533 /**
   5534  * insert vector at position index
   5535  * the data in vector name is moved and
   5536  * the data in vector is copied to vector name
   5537  */
   5538 #define vectorInsert(name, index, vector) do {\
   5539   var UNIQVAR(idx) = index;\
   5540   var UNIQVAR(vec) = vector;\
   5541   if (UNIQVAR(idx) == (name)->count) {\
   5542     vectorAppend(name, UNIQVAR(vec));\
   5543   }\
   5544   else if (sizeof((name)->array[0]) == sizeof((UNIQVAR(vec))->array[0])) {\
   5545     if (((name)->count + (UNIQVAR(vec))->count) > (name)->maxCount)\
   5546       vectorResize(name, (name)->count + (UNIQVAR(vec))->count);\
   5547     memmove((name)->array + UNIQVAR(idx) + (UNIQVAR(vec))->count, (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
   5548     memcpy((name)->array + UNIQVAR(idx), (UNIQVAR(vec))->array, (UNIQVAR(vec))->count * sizeof (name)->array[0]);\
   5549     (name)->count += (UNIQVAR(vec))->count;\
   5550   }\
   5551   } while(0)
   5552 
   5553 /**
   5554  * insert array at position index
   5555  * the data in vector is moved and
   5556  * the data in array is copied to vector
   5557  */
   5558 #define vectorInsertFrom(name, index, array, countInt) do {\
   5559   var UNIQVAR(idx) = index;\
   5560   var UNIQVAR(c)   = countInt;\
   5561   var UNIQVAR(a)   = array;\
   5562   if (UNIQVAR(idx) == (name)->count) {\
   5563     vectorAppendFrom(name, UNIQVAR(a), UNIQVAR(c));\
   5564   }\
   5565   else if (sizeof((name)->array[0]) == sizeof(UNIQVAR(a)[0])) {\
   5566     if (((name)->count + UNIQVAR(c)) > (name)->maxCount)\
   5567       vectorResize(name, (name)->count + UNIQVAR(c));\
   5568     memmove((name)->array + UNIQVAR(idx) + UNIQVAR(c), (name)->array + UNIQVAR(idx), ((name)->count - UNIQVAR(idx)) * sizeof (name)->array[0]);\
   5569     memcpy((name)->array + UNIQVAR(idx), UNIQVAR(a), UNIQVAR(c) * sizeof (name)->array[0]);\
   5570     (name)->count += UNIQVAR(c);\
   5571   }\
   5572   } while(0)
   5573 
   5574 /**
   5575  * slice vector, keep only elements between start and end
   5576  * start must be between 0 and last index
   5577  * end must be between 1 and count
   5578  * the vector is returned
   5579  */
   5580 #define vectorSlice sliceSlice
   5581 
   5582 /**
   5583  * copy vector elements between start and end to a new vector
   5584  * start must be between 0 and last index
   5585  * end must be between 1 and count
   5586  * the new vector is returned and must be freed with vectorTerminate
   5587  */
   5588 #define vectorCopy(name, start, end) ({\
   5589   var UNIQVAR(strt) = start;\
   5590   var UNIQVAR(ed)   = end;\
   5591   createAllocateVectorCount(typeof(*(name)),UNIQVAR(r), UNIQVAR(ed) - UNIQVAR(strt));\
   5592   memcpy(UNIQVAR(r)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
   5593   UNIQVAR(r)->count = UNIQVAR(ed) - UNIQVAR(strt);\
   5594   UNIQVAR(r);\
   5595   })
   5596 
   5597 /**
   5598  * copy vector elements between start and end to the dest vector
   5599  * start must be between 0 and last index
   5600  * end must be between 1 and count
   5601  */
   5602 #define vectorBCopy(name, dest, start, end) do{\
   5603   if (sizeof((name)->array[0]) == sizeof((dest)->array[0])) {\
   5604     var UNIQVAR(strt) = start;\
   5605     var UNIQVAR(ed)   = end;\
   5606     if ((UNIQVAR(ed) - UNIQVAR(strt)) > (dest)->maxCount)\
   5607       vectorResize(dest, UNIQVAR(ed) - UNIQVAR(strt));\
   5608     memcpy((dest)->array, (name)->array + UNIQVAR(strt), (UNIQVAR(ed) - UNIQVAR(strt)) * sizeof (name)->array[0]);\
   5609     (dest)->count = UNIQVAR(ed) - UNIQVAR(strt);\
   5610   }\
   5611   } while(0)
   5612 
   5613 /**
   5614  * sort the vector
   5615  * the compareFunction must prototype of type:
   5616  * int cmp(const void * a, const void * b);
   5617  * the results of the compareFunction should be:
   5618  * <0 when a < b
   5619  * 0  when a = b
   5620  * >0 when a > b
   5621  */
   5622 #define vectorSort sliceSort
   5623 
   5624 /**
   5625  * return true when vector name is equal to vector
   5626  * eqFunction should return true when the elements are equal
   5627  * eqFunction can be either a macro or a function
   5628  */
   5629 #define vectorEq sliceEq
   5630 
   5631 /**
   5632  * return true when vector has value
   5633  * eqFunction should return true when the elements are equal
   5634  * eqFunction can be either a macro or a function
   5635  */
   5636 #define vectorHas sliceHas
   5637 
   5638 /**
   5639  * return index (ssize_t) of value in vector
   5640  * eqFunction should return true when the elements are equal
   5641  * eqFunction can be either a macro or a function
   5642  *
   5643  * return value is -1 when value is not found
   5644  */
   5645 #define vectorIndexOf sliceIndexOf
   5646 
   5647 /**
   5648  * binary search value in vector
   5649  *
   5650  * efficiently finds the index of value in vector
   5651  * the vector has to be sorted before calling vectorBinarySearch
   5652  *
   5653  * less is a macro taking an index and the search value returning 1 when vectorAt(name,index) is less than value:
   5654  * #define less(index, value) vectorAt(name, index) < value
   5655  *
   5656  * equal is a macro returning 1 when vectorAt(name,index) is equal to value:
   5657  * #define equal(index, value) vectorAt(name,index) == value
   5658  *
   5659  * return value is -1 when value is not found
   5660  */
   5661 #define vectorBinarySearch sliceBinarySearch
   5662 
   5663 /**
   5664  * Uniquify elements in vector
   5665  * each elements are unique in the vector
   5666  *
   5667  * eqFunction should return true when the elements are equal
   5668  * eqFunction can be either a macro or a function
   5669  */
   5670 #define vectorUniq sliceUniq
   5671 
   5672 /*
   5673  * end vector
   5674  */
   5675 
   5676 
   5677 /**
   5678  * dynamic segmented vector
   5679  *
   5680  * this type of array is faster than vector when there are many elements and has a dynamic element count
   5681  * pushing elements into the array increases the element count
   5682  * the data is stored in static array segments
   5683  *
   5684  * no sanity checks are done
   5685  *
   5686  * usage examples: regular array, stack
   5687  *
   5688  * the prefix is dVector
   5689  *
   5690  * Usage:
   5691  *
   5692  * to declare an array:
   5693  *
   5694  * dVectorT(typeName, type);
   5695  *
   5696  * typeName dvector;
   5697  *
   5698  * dVectorInit(&dvector);
   5699  * or
   5700  * dVectorInitCount(&dvector, 17);
   5701  *
   5702  * dVectorAppend(&dvector, value);
   5703  *
   5704  * // get an element
   5705  * int a                = dVectorAt(&dvector, 0);
   5706  *
   5707  * set
   5708  * dVectorAt(&dvector, 1) = 3;
   5709  *
   5710  * dVectorFree(&dvector);
   5711  *
   5712  * dVector variables:
   5713  * dvector.maxCount: maximum element count allowed
   5714  *
   5715  * Note: dont combine the macros, it gives wrong results:
   5716  *       a = dVectorAt(&dvector, dVectorPop(&dvector2));
   5717  *       dVectorPop is run several time, more than one element is popped
   5718  *
   5719  * Note: some functions are macros to be able to have structs as element and
   5720  *       access the struct members directly, for example:
   5721  *         dVectorLast(chan).a = 0;
   5722  */
   5723 
   5724 // user parameters
   5725 /**
   5726  * chunk size: 2^dVectorBits elements
   5727  */
   5728 #define dVectorBits 6
   5729 // user parameters end
   5730 
   5731 #define dVectorSz   (1<<dVectorBits)
   5732 #define dVectorMask (dVectorSz-1)
   5733 
   5734 /**
   5735  * declares type for dynamic array
   5736  *
   5737  * \param
   5738  * typeName dVector type name
   5739  * \param
   5740  * element type of elements (int, struct, pointer...)
   5741  */
   5742 #define dVectorT(typeName, elementType)\
   5743   typedef struct {\
   5744     int64_t    count;\
   5745     int64_t    maxCount;\
   5746     void**      buffers;\
   5747     elementType element;\
   5748   } typeName
   5749 
   5750 
   5751 #define createDVector(typeName, name) ;typeName name; dVectorInit(&name)
   5752 
   5753 #define createDVectorCount(typeName, name, count) ;typeName name; dVectorInitCount(&name, count)
   5754 
   5755 /**
   5756  * initialize dynamic array with minimum element count
   5757  *
   5758  * \param
   5759  * a variable name for dVector
   5760  */
   5761 #define dVectorInit(a) do{\
   5762     (a)->count            = 0;\
   5763     (a)->buffers          = malloc(sizeof(void*));\
   5764     (a)->buffers[0]       = malloc(dVectorSz * sizeof((a)->element));\
   5765     (a)->maxCount         = 1;\
   5766   }while(0)
   5767 
   5768 
   5769 /**
   5770  * initialize dynamic array and count
   5771  *
   5772  * \param
   5773  * a variable name for dVector
   5774  * \param
   5775  * count initial element count for name type
   5776  */
   5777 #define dVectorInitCount(a, count) do{\
   5778     dVectorInit(a);\
   5779     if (count > dVectorSz) {\
   5780       (a)->buffers = realloc((a)->buffers, ((count>>dVectorBits)+1) * sizeof(void*));\
   5781       rangeFrom(UNIQVAR(i), 1, (count>>dVectorBits)+1) {\
   5782         (a)->buffers[UNIQVAR(i)] = malloc(dVectorSz * sizeof((a)->element));\
   5783       }\
   5784       (a)->maxCount = (count>>dVectorBits)+1;\
   5785     }\
   5786   }while(0)
   5787 
   5788 #define dVectorResize(a, count) do{\
   5789     if (count > (a)->maxCount * dVectorSz) {\
   5790       /* grow array */\
   5791       (a)->buffers = realloc((a)->buffers, ((count>>dVectorBits)+1) * sizeof(void*));\
   5792       rangeFrom(UNIQVAR(i), (a)->maxCount, (count>>dVectorBits)+1) {\
   5793         (a)->buffers[UNIQVAR(i)] = malloc(dVectorSz * sizeof((a)->element));\
   5794       }\
   5795       (a)->maxCount = (count>>dVectorBits)+1;\
   5796     }\
   5797     /*else TODO dVector shrink */\
   5798   }while(0)
   5799 
   5800 /**
   5801  * free the internal buffers
   5802  *
   5803  * \param
   5804  * a dynamic array
   5805  */
   5806 #define dVectorFree(a) do{\
   5807     range(UNIQVAR(i), (size_t)(a)->maxCount) {\
   5808       free((a)->buffers[UNIQVAR(i)]);\
   5809     }\
   5810     free((a)->buffers);\
   5811   }while(0)
   5812 
   5813 /**
   5814  * element type in vector
   5815  */
   5816 #define dVectorElemType(name) typeof((name)->element)
   5817 
   5818 /**
   5819  * element pointer type in vector
   5820  */
   5821 #define dVectorElemPtrType(name) typeof(&(name)->element)
   5822 
   5823 /**
   5824  * Empty Array
   5825  * Allocated buffers in the array must be freed before running dVectorEmpty
   5826  */
   5827 #define dVectorEmpty(name) (name)->count = 0
   5828 
   5829 /**
   5830  * is Array Empty
   5831  */
   5832 #define dVectorIsEmpty(name) ((name)->count == 0)
   5833 
   5834 /**
   5835  * return element count
   5836  */
   5837 #define dVectorCount(name) (name)->count
   5838 
   5839 /**
   5840  * return max element count
   5841  */
   5842 #define dVectorMaxCount(name) ((name)->maxCount * dVectorSz)
   5843 
   5844 /**
   5845  * allocate buffer for new elements
   5846  * only when the array is full
   5847  *
   5848  * \param
   5849  * a dynamic array
   5850  */
   5851 #define dVectorAlloc(a) do{\
   5852     if ((a)->count == dVectorMaxCount(a)) {\
   5853       (a)->maxCount++;\
   5854       (a)->buffers = realloc((a)->buffers, (a)->maxCount * sizeof(void*));\
   5855       (a)->buffers[(a)->maxCount-1] = malloc(dVectorSz * sizeof((a)->element));\
   5856     }\
   5857   }while(0)
   5858 
   5859 /**
   5860  * push element and expand the dynamic array
   5861  * no data (random) is set in the new element.
   5862  *
   5863  * \param
   5864  * a dynamic array
   5865  * \param
   5866  * v element to push
   5867  */
   5868 #define dVectorPush(a) do{\
   5869     dVectorAlloc(a);\
   5870     (a)->count++;\
   5871   }while(0)
   5872 
   5873 /**
   5874  * append element and expand the dynamic array
   5875  *
   5876  * \param
   5877  * a dynamic array
   5878  * \param
   5879  * v element to push
   5880  */
   5881 #define dVectorAppend(a, v) do{\
   5882     dVectorAlloc(a);\
   5883     if ((a)->count < dVectorMaxCount(a)) {\
   5884       typeof((a)->element) *UNIQVAR(buffer) = (a)->buffers[((a)->count)>>dVectorBits];\
   5885       *(UNIQVAR(buffer)+ (((a)->count)&dVectorMask)) = v;\
   5886       (a)->count++;\
   5887     }\
   5888   }while(0)
   5889 
   5890 /**
   5891  * pop element
   5892  * the index of the last element is decreased
   5893  *
   5894  * NOTE: using comma operator to avoid warning
   5895  * warning: operation on ‘b.head’ may be undefined [-Wsequence-point]
   5896  *
   5897  *
   5898  * \param
   5899  * a dynamic array
   5900  */
   5901 #define dVectorPop(a) ((a)->count--, *((typeof((a)->element)*)((a)->buffers[((a)->count)>>dVectorBits])+(((a)->count)&dVectorMask)))
   5902 
   5903 /**
   5904  * delete the last element
   5905  * useful for avoiding warning: right-hand operand of comma expression has no effect
   5906  * when the poped value is not used
   5907  */
   5908 #define dVectorDelLast(a) ((a)->count--)
   5909 
   5910 // TODO poor perfomance #define dVectorPrepend(a, v)
   5911 
   5912 // TODO poor perfomance #define dVectorDequeue(a)
   5913 
   5914 // TODO poor perfomance #define dVectorDelFirst(a)
   5915 
   5916 /**
   5917  * get / set element at index
   5918  *
   5919  * \param
   5920  * a dynamic array
   5921  * \param
   5922  * index index in array
   5923  */
   5924 #define dVectorAt(a, index) (*((typeof((a)->element)*)((a)->buffers[(index)>>dVectorBits])+((index)&dVectorMask)))
   5925 
   5926 /**
   5927  * get pointer to element at index
   5928  *
   5929  * \param
   5930  * a dynamic array
   5931  * \param
   5932  * index index in array
   5933  */
   5934 #define dVectorPtr(a, index) ((typeof((a)->element)*)((a)->buffers[(index)>>dVectorBits])+((index)&dVectorMask))
   5935 
   5936 /**
   5937  * last element
   5938  *
   5939  * \param
   5940  * a dynamic array
   5941  */
   5942 #define dVectorLast(a) (*((typeof((a)->element)*)((a)->buffers[((a)->count-1)>>dVectorBits])+(((a)->count-1)&dVectorMask)))
   5943 
   5944 /**
   5945  * pointer to last element
   5946  *
   5947  * \param
   5948  * a dynamic array
   5949  */
   5950 #define dVectorLastPtr(a) ((typeof((a)->element)*)((a)->buffers[((a)->count-1)>>dVectorBits])+(((a)->count-1)&dVectorMask))
   5951 
   5952 /**
   5953  * index of last element
   5954  */
   5955 #define dVectorLastIndex(a) ((a)->count-1)
   5956 
   5957 /**
   5958  * first element
   5959  *
   5960  * \param
   5961  * a dynamic array
   5962  */
   5963 #define dVectorFirst(a) (*((typeof((a)->element)*)((a)->buffers[0])))
   5964 
   5965 /**
   5966  * write the dVector content to filename file
   5967  * No NULL checks are done on the parameters
   5968  *
   5969  * \param
   5970  *    filename file name string
   5971  */
   5972 #define dVectorWriteFilename(a, filename) do {\
   5973     FILE *UNIQVAR(f) = fopen(filename, "w");\
   5974     if (UNIQVAR(f)) {\
   5975       range(UNIQVAR(i), (size_t)dVectorCount(a)) {\
   5976         typeof((a)->element) *firstElement = (a)->buffers[UNIQVAR(i)/dVectorSz];\
   5977         fwrite(firstElement+(UNIQVAR(i)%dVectorSz), 1, sizeof((a)->element), UNIQVAR(f));\
   5978       }\
   5979       fclose(UNIQVAR(f));\
   5980     }\
   5981   } while(0)
   5982 
   5983 /**
   5984  * write the dVector content to disk
   5985  * No NULL checks are done on the parameters
   5986  *
   5987  * \param
   5988  *    file already opened file
   5989  */
   5990 #define dVectorWrite(a, file) do {\
   5991     range(UNIQVAR(i), (size_t)dVectorCount(a)) {\
   5992       typeof((a)->element) *firstElement = (a)->buffers[UNIQVAR(i)/dVectorSz];\
   5993       fwrite(firstElement+(UNIQVAR(i)%dVectorSz), 1, sizeof((a)->element), file);\
   5994     }\
   5995   } while(0)
   5996 
   5997 /**
   5998  * read a dVector from filename file
   5999  * No NULL checks are done on the parameters
   6000  *
   6001  * \param
   6002  * filename file name string
   6003  */
   6004 #define dVectorReadFilename(a, filename) do {\
   6005     if (fileExists(filename)) {\
   6006       size_t UNIQVAR(sz) = fileSize(filename);\
   6007       FILE *UNIQVAR(f) = fopen(filename, "r");\
   6008       if (UNIQVAR(f)) {\
   6009         range(UNIQVAR(i), UNIQVAR(sz)/sizeof((a)->element)) {\
   6010           dVectorPush(a);\
   6011           fread(dVectorLastPtr(a), 1, sizeof((a)->element), UNIQVAR(f));\
   6012         }\
   6013         fclose(UNIQVAR(f));\
   6014       }\
   6015     }\
   6016   } while(0)
   6017 
   6018 /**
   6019  * read a dVector from disk
   6020  * No NULL checks are done on the parameters
   6021  *
   6022  * \param
   6023  *    file already opened file
   6024  */
   6025 #define dVectorRead(a, file) do {\
   6026     fseek(file, 0 , SEEK_END);\
   6027     size_t UNIQVAR(sz) = ftell(file);\
   6028     fseek(file, 0 , SEEK_SET);\
   6029     range(UNIQVAR(i), UNIQVAR(sz)/sizeof((a)->element)) {\
   6030       dVectorPush(a);\
   6031       fread(dVectorLastPtr(a), 1, sizeof((a)->element), file);\
   6032     }\
   6033   } while(0)
   6034 
   6035 /**
   6036  * loop on dVector elements
   6037  * element is a pointer to a value in the array
   6038  *
   6039  * dVectorForEach(&vec, e) {
   6040  *    e->x = 0;
   6041  * }
   6042  */
   6043 #define dVectorForEach(name, element) \
   6044   ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
   6045   for (dVectorElemPtrType(name) element = dVectorPtr(name, 0) ; UNIQVAR(libsheepyInternalIndex) < (name)->count ; UNIQVAR(libsheepyInternalIndex)++, element = dVectorPtr(name, UNIQVAR(libsheepyInternalIndex)))
   6046 
   6047 /**
   6048  * enumerate dVector elements
   6049  * index is the position of the element in the array
   6050  * index is declared as size_t and is available after the loop
   6051  * element is a pointer to a value in the array
   6052  *
   6053  * dVectorEnumerate(&vec, i, e) {
   6054  *    e->x = 0;
   6055  *    printf("dVectorEnumerate %d\n", i);
   6056  * }
   6057  */
   6058 #define dVectorEnumerate(name, index, element) \
   6059   ; size_t index = 0 ; \
   6060   for (dVectorElemPtrType(name) element = dVectorPtr(name, 0) ; index < (name)->count ; index++, element = dVectorPtr(name, index))
   6061 
   6062 
   6063 
   6064 /*
   6065  * end dynamic segmented vector
   6066  */
   6067 
   6068 
   6069 /**
   6070  * staticArray type definition
   6071  *
   6072  * this type of array has a static maximum element count (fixed)
   6073  * staticArray has head and last indexes, this allows dequeuing from head elements fast
   6074  * it is used as a circular buffer, queue, fifo...
   6075  * a ring is a pointer to a staticArray
   6076  *
   6077  * no sanity checks are done
   6078  *
   6079  * Usage:
   6080  *
   6081  * to declare an array:
   6082  *
   6083  * typedef struct {
   6084  *   int a;
   6085  *   char *key;
   6086  * } element;
   6087  *
   6088  * staticArrayT(typeName, element, 10);
   6089  *
   6090  * typeName array;
   6091  * staticArrayInit(array);
   6092  *
   6093  * staticArrayPush(array);
   6094  * staticArrayLast(array).a = fork();
   6095  *
   6096  * val = staticArrayLast(array).a;
   6097  * staticArrayPop(array);
   6098  *
   6099  * Array variables:
   6100  * array.list:     elements
   6101  * array.maxCount: maximum element count allowed
   6102  *
   6103  * Note: some functions are macros to be able to have structs as element and
   6104  *       access the struct members directly, for example:
   6105  *         staticArrayLast(chan).a = 0;
   6106  */
   6107 
   6108 //
   6109 // TODO add print elements func
   6110 // TODO check boundaries
   6111 
   6112 /**
   6113  * base type for all staticArrays and rings
   6114  */
   6115 typedef struct {
   6116   i64 last; // last element
   6117   i64 head;
   6118   i64 maxCount;
   6119   bool isEmpty;
   6120 } staticArrayBase;
   6121 
   6122 /**
   6123  * declares type for staticArray or ring
   6124  *
   6125  * \param
   6126  * typeName staticArray/ring type name
   6127  * \param
   6128  * element type of elements (int, struct, pointer...)
   6129  * \param
   6130  * MAXCOUNT array/ring buffer size
   6131  */
   6132 #define staticArrayT(typeName, element, MAXCOUNT)\
   6133   typedef struct {\
   6134     i64 last;\
   6135     i64 head;\
   6136     i64 maxCount;\
   6137     bool isEmpty;\
   6138     element list[MAXCOUNT];\
   6139   } typeName;
   6140 
   6141 #define createStaticArray(typeName, name) ;typeName name; staticArrayInit(name)
   6142 
   6143 /**
   6144  * initialize count in array/static ring
   6145  * this macro can initialize rings if the struct is accessed directly
   6146  *
   6147  * \param
   6148  * name variable name for staticArray
   6149  */
   6150 #define staticArrayInit(name)\
   6151   do{\
   6152     (name).last = (name).head = 0;\
   6153     (name).maxCount = COUNT_ELEMENTS((name).list);\
   6154     (name).isEmpty = true;\
   6155   } while(0);
   6156 
   6157 /**
   6158  * element type in array
   6159  */
   6160 #define staticArrayElemType(name) typeof((name).list[0])
   6161 
   6162 /**
   6163  * element pointer type in array
   6164  */
   6165 #define staticArrayElemPtrType(name) typeof(&(name).list[0])
   6166 
   6167 /**
   6168  * Empty Array
   6169  * Allocated buffers in the list must be freed before running staticArrayEmpty
   6170  */
   6171 #define staticArrayEmpty(name)\
   6172   do{\
   6173     (name).last = (name).head = 0;\
   6174     (name).isEmpty = true;\
   6175   } while(0);
   6176 
   6177 /**
   6178  * is Array Empty
   6179  */
   6180 #define staticArrayIsEmpty(name) ((name).isEmpty)
   6181 
   6182 /**
   6183  * is Array Full
   6184  */
   6185 #define staticArrayIsFull(name) ((name).isEmpty ? 0 : ((((name).last+1) % (name).maxCount) == (name).head))
   6186 
   6187 /**
   6188  * return elements count
   6189  */
   6190 #define staticArrayCount(name) ((name).isEmpty ? 0 : ((((name).last) >= ((name).head)) ? ((name).last-(name).head+1) : (((name).maxCount-(name).head + (name).last+1))) )
   6191 
   6192 /**
   6193  * push element to array (only increases last)
   6194  * use staticArrayLast to access the element
   6195  */
   6196 #define staticArrayPush(name)\
   6197   do{\
   6198     if ((name).isEmpty) {\
   6199       (name).isEmpty = false;\
   6200     }\
   6201     else {\
   6202       (name).last++;\
   6203       (name).last %= (name).maxCount;\
   6204     }\
   6205   } while(0);
   6206 
   6207 /**
   6208  * pop element from array (only decreases last)
   6209  */
   6210 #define staticArrayPop(name)\
   6211   do{\
   6212     if (!(name).isEmpty && ((name).last == (name).head)) {\
   6213       (name).isEmpty = true;\
   6214     }\
   6215     else if (!(name).isEmpty && ((name).last != (name).head)) {\
   6216       if ((name).last)\
   6217         (name).last--;\
   6218       else\
   6219         (name).last+=(name).maxCount-1;\
   6220     }\
   6221   } while(0);
   6222 
   6223 #define staticArrayDelLast staticArrayPop
   6224 
   6225 /**
   6226  * prepend element to array (only decreases head)
   6227  * use staticArrayFirst to access the element
   6228  */
   6229 #define staticArrayPrepend(name)\
   6230   do{\
   6231     if ((name).isEmpty) {\
   6232       (name).isEmpty = false;\
   6233     }\
   6234     else {\
   6235       if ((name).head)\
   6236         (name).head--;\
   6237       else\
   6238         (name).head+=(name).maxCount-1;\
   6239     }\
   6240   } while(0);
   6241 
   6242 /**
   6243  * dequeue element from array (only increases head)
   6244  */
   6245 #define staticArrayDequeue(name)\
   6246   do{\
   6247     if (!(name).isEmpty && ((name).last == (name).head)) {\
   6248       (name).isEmpty = true;\
   6249     }\
   6250     else if (!(name).isEmpty && ((name).last != (name).head)) {\
   6251       (name).head++;\
   6252       (name).head %= (name).maxCount;\
   6253     }\
   6254   } while(0);
   6255 
   6256 #define staticArrayDelFirst staticArrayDequeue
   6257 
   6258 /**
   6259  * get element at index, negative index is supported
   6260  */
   6261 #define staticArrayGet(name, index) (name).list[(((index) >= 0) ? (index) : staticArrayCount(name) + (index) )]
   6262 #define staticArrayAt staticArrayGet
   6263 
   6264 /**
   6265  * index of element for an index relative to 0, negative index is supported
   6266  */
   6267 #define staticArrayGetIndex(name, index) ((((index) >= 0) ? (index) : staticArrayCount(name) + (index) ))
   6268 
   6269 /**
   6270  * get element at index with name->head index 0, negative index is supported
   6271  */
   6272 #define staticArrayRef(name, index) (name).list[((((index) >= 0) ? (index) : staticArrayCount(name) + (index) ) + name.head) % name.maxCount]
   6273 
   6274 /**
   6275  * index of element for an index relative to head, negative index is supported
   6276  */
   6277 #define staticArrayRefIndex(name, index) (((((index) >= 0) ? (index) : staticArrayCount(name) + (index) ) + name.head) % name.maxCount)
   6278 
   6279 /**
   6280  * last element in array
   6281  */
   6282 #define staticArrayLast(name) (name).list[(name).last]
   6283 
   6284 /**
   6285  * index of last element
   6286  */
   6287 #define staticArrayLastIndex(name) (name).last
   6288 
   6289 /**
   6290  * first element in array
   6291  */
   6292 #define staticArrayFirst(name) (name).list[(name).head]
   6293 
   6294 /**
   6295  * index of first element
   6296  */
   6297 #define staticArrayFirstIndex(name) (name).head
   6298 
   6299 /**
   6300  * delete an element in the array and move elements after it to fill the gap
   6301  */
   6302 #define staticArrayDelElem(name, index) do {\
   6303     if ((name).head < (name).last) {\
   6304       /* move elements after index in latest static array */\
   6305       if (index < (name).last) {\
   6306         memmove(&(name).list[index], &(name).list[index+1], ((name).last - index) * sizeof((name).list[0]));\
   6307       }\
   6308     }\
   6309     elif ((name).head > (name).last) {\
   6310       if (index >= (name).head) {\
   6311         /* move elements after index in latest static array */\
   6312         if (index < (name).maxCount - 1) {\
   6313           memmove(&(name).list[index], &(name).list[index+1], ((name).maxCount - index -1) * sizeof((name).list[0]));\
   6314         }\
   6315         /* move list[0] to list[maxCount-1] */\
   6316         /* then shift elements in [1..last+1] to [0..last] if needed */\
   6317         staticArrayAt((name), (name).maxCount-1) = staticArrayAt((name), 0);\
   6318         if ((name).last > 0) {\
   6319           memmove(&(name).list[0], &(name).list[1], (name).last * sizeof((name).list[0]));\
   6320         }\
   6321       }\
   6322       else {\
   6323         /* 0 < index < last+1 */\
   6324         /* move elements after index in latest static array */\
   6325         if (index < (name).last) {\
   6326           memmove(&(name).list[index], &(name).list[index+1], ((name).last - index) * sizeof((name).list[0]));\
   6327         }\
   6328       }\
   6329     }\
   6330     staticArrayDelLast((name));\
   6331   } while(0)
   6332 
   6333 /**
   6334  * write the staticArray content to filename file
   6335  * No NULL checks are done on the parameters
   6336  *
   6337  * \param
   6338  *    filename file name string
   6339  */
   6340 #define staticArrayWriteFilename(name, filename) do {\
   6341     FILE *UNIQVAR(f) = fopen(filename, "w");\
   6342     if (UNIQVAR(f)) {\
   6343       if ((name).head <= (name).last) {\
   6344         fwrite(&((name).list[(name).head]), 1, (size_t)staticArrayCount(name) * sizeof((name).list[0]), UNIQVAR(f));\
   6345       } else {\
   6346         /* write from head to maxcount and then from 0 to last*/\
   6347         fwrite(&((name).list[(name).head]), 1, (size_t)((name).maxCount - (name).head) * sizeof((name).list[0]), UNIQVAR(f));\
   6348         fwrite(&((name).list[(name).head])+((name).maxCount - (name).head), 1, (size_t)((name).last+1) * sizeof((name).list[0]), UNIQVAR(f));\
   6349       }\
   6350       fclose(UNIQVAR(f));\
   6351     }\
   6352   } while(0)
   6353 
   6354 /**
   6355  * write the staticArray content to disk
   6356  * No NULL checks are done on the parameters
   6357  *
   6358  * \param
   6359  *    file already opened file
   6360  */
   6361 #define staticArrayWrite(name, file) do {\
   6362     if ((name).head <= (name).last) {\
   6363       fwrite(&((name).list[(name).head]), 1, (size_t)staticArrayCount(name) * sizeof((name).list[0]), file);\
   6364     } else {\
   6365       /* write from head to maxcount and then from 0 to last*/\
   6366       fwrite(&((name).list[(name).head]), 1, (size_t)((name).maxCount - (name).head) * sizeof((name).list[0]), file);\
   6367       fwrite(&((name).list[(name).head])+((name).maxCount - (name).head), 1, (size_t)((name).last+1) * sizeof((name).list[0]), file);\
   6368     }\
   6369   } while(0)
   6370 
   6371 /**
   6372  * read name staticArray from filename file
   6373  * No NULL checks are done on the parameters
   6374  *
   6375  * \param
   6376  * filename file name string
   6377  */
   6378 #define staticArrayReadFilename(name, filename) do {\
   6379     if (fileExists(filename)) {\
   6380       size_t UNIQVAR(sz) = fileSize(filename);\
   6381       if (UNIQVAR(sz) > sizeof((name).list)) break;\
   6382       /* check that UNIQVAR(sz) is a multiple of sizeof((name).list[0]), if not the file data doesnt fit the array */\
   6383       if (UNIQVAR(sz) % sizeof((name).list[0])) break;\
   6384       FILE *UNIQVAR(f) = fopen(filename, "r");\
   6385       if (UNIQVAR(f)) {\
   6386         fread((name).list, 1, UNIQVAR(sz), UNIQVAR(f));\
   6387         fclose(UNIQVAR(f));\
   6388         (name).head = 0;\
   6389         if (UNIQVAR(sz)) {\
   6390           (name).last    = (UNIQVAR(sz) / sizeof((name).list[0])) - 1;\
   6391           (name).isEmpty = false;\
   6392         }\
   6393         else {\
   6394           (name).last    = 0;\
   6395           (name).isEmpty = true;\
   6396         }\
   6397       }\
   6398     }\
   6399   } while(0)
   6400 
   6401 /**
   6402  * read name staticArray from disk
   6403  * No NULL checks are done on the parameters
   6404  *
   6405  * \param
   6406  *    file already opened file
   6407  */
   6408 #define staticArrayRead(name, file) do {\
   6409     fseek(file, 0 , SEEK_END);\
   6410     size_t UNIQVAR(sz) = ftell(file);\
   6411     fseek(file, 0 , SEEK_SET);\
   6412     if (UNIQVAR(sz) > sizeof((name).list)) break;\
   6413     /* check that UNIQVAR(sz) is a multiple of sizeof((name).list[0]), if not the file data doesnt fit the array */\
   6414     if (UNIQVAR(sz) % sizeof((name).list[0])) break;\
   6415     fread((name).list, 1, UNIQVAR(sz), file);\
   6416     (name).head = 0;\
   6417     if (UNIQVAR(sz)) {\
   6418       (name).last    = (UNIQVAR(sz) / sizeof((name).list[0])) - 1;\
   6419       (name).isEmpty = false;\
   6420     }\
   6421     else {\
   6422       (name).last    = 0;\
   6423       (name).isEmpty = true;\
   6424     }\
   6425   } while(0)
   6426 
   6427 /**
   6428  * loop on staticArray elements
   6429  * element is a pointer to a value in the array
   6430  *
   6431  * staticArrayForEach(sa, e) {
   6432  *    e->x = 0;
   6433  * }
   6434  */
   6435 #define staticArrayForEach(name, element) \
   6436   ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
   6437   for (staticArrayElemPtrType(name) element = &staticArrayRef(name, 0) ; UNIQVAR(libsheepyInternalIndex) < staticArrayCount(name) ; UNIQVAR(libsheepyInternalIndex)++, element = &staticArrayRef(name, UNIQVAR(libsheepyInternalIndex)))
   6438 
   6439 /**
   6440  * enumerate staticArray elements
   6441  * index is the position of the element in the array
   6442  * index is declared as size_t and is available after the loop
   6443  * element is a pointer to a value in the array
   6444  *
   6445  * staticArrayEnumerate(sa, i, e) {
   6446  *    e->x = 0;
   6447  *    printf("staticArrayEnumerate %d\n", i);
   6448  * }
   6449  */
   6450 #define staticArrayEnumerate(name, index, element) \
   6451   ;size_t UNIQVAR(libsheepyInternalIndex) = 0; \
   6452   ; size_t index = name.head ; \
   6453   for (staticArrayElemPtrType(name) element = &staticArrayRef(name, 0) ; UNIQVAR(libsheepyInternalIndex) < staticArrayCount(name) ; UNIQVAR(libsheepyInternalIndex)++, index = (name.head + UNIQVAR(libsheepyInternalIndex)) % name.maxCount, element = &staticArrayRef(name, index))
   6454 
   6455 /**
   6456  * indexer is a staticArray without the list
   6457  * It indexes an independent array
   6458  *
   6459  * Usage:
   6460  *
   6461  * declare an array:
   6462  * char array[10][5];
   6463  *
   6464  * declare an indexer:
   6465  * indexer indx;
   6466  *
   6467  * or declare an indexer with smaller counters (default is int64_t):
   6468  * indexerT(typeName, i8);
   6469  * typeName indx;
   6470  *
   6471  * indexerInit(indx, 10);
   6472  *
   6473  * indexerPush(indx);
   6474  * array[indexerLast(indx)][0] = '0';
   6475  *
   6476  * // or
   6477  * indexerPush(indx);
   6478  * array[indx.last][0] = '0';
   6479  *
   6480  * indexerPop(indx);
   6481  *
   6482  * // accessing the first/head element
   6483  *
   6484  * char c = array[indexerFirst(indx)][0];
   6485  * char c = array[indx.head][0];
   6486  *
   6487  *
   6488  * For pointer to indexers (idxP), use:
   6489  * indexerPInit,
   6490  * indexerPEmpty,
   6491  * indexerPIsEmpty,
   6492  * indexerPIsFull,
   6493  * indexerPCount,
   6494  * indexerPPush,
   6495  * indexerPPop,
   6496  * indexerPPrepend,
   6497  * indexerPDequeue,
   6498  * indexerPRef,
   6499  * indexerPLast or idxP->last,
   6500  * indexerPFirst or idxP->head
   6501  *
   6502  */
   6503 
   6504 /**
   6505  * base type, same as staticArray
   6506  */
   6507 #define indexer staticArrayBase
   6508 
   6509 /**
   6510  * declare an indexer type with INT_TYPE counters instead of the default i64
   6511  * INT_TYPE has to be signed integer
   6512  *
   6513  * The indexers of this type are not compatible with the indexerP* functions
   6514  */
   6515 #define indexerT(typeName, INT_TYPE)\
   6516   typedef struct {\
   6517     INT_TYPE last;\
   6518     INT_TYPE head;\
   6519     INT_TYPE maxCount;\
   6520     bool isEmpty;\
   6521   } typeName;
   6522 
   6523 #define createIndexer(typeName, name, maxCount) ;typeName name; indexerInit(name, maxCount)
   6524 
   6525 /**
   6526  * initialize count in array/static ring
   6527  * this macro can initialize rings if the struct is accessed directly
   6528  *
   6529  * \param
   6530  * name variable name for staticArray
   6531  * \param
   6532  * MAXCOUNT max count for name type
   6533  */
   6534 #define indexerInit(name, MAXCOUNT)\
   6535   do{\
   6536     (name).last = (name).head = 0;\
   6537     (name).maxCount = MAXCOUNT;\
   6538     (name).isEmpty = true;\
   6539   } while(0);
   6540 
   6541 #define indexerPInit ringInit
   6542 
   6543 /**
   6544  * Empty Array
   6545  * Allocated buffers in the list must be freed before running staticArrayEmpty
   6546  */
   6547 #define indexerEmpty staticArrayEmpty
   6548 #define indexerPEmpty ringEmpty
   6549 
   6550 /**
   6551  * is Array Empty
   6552  */
   6553 #define indexerIsEmpty staticArrayIsEmpty
   6554 #define indexerPIsEmpty ringIsEmpty
   6555 
   6556 /**
   6557  * is Array Full
   6558  */
   6559 #define indexerIsFull staticArrayIsFull
   6560 #define indexerPIsFull ringIsFull
   6561 
   6562 /**
   6563  * return elements count
   6564  */
   6565 #define indexerCount staticArrayCount
   6566 #define indexerPCount ringCount
   6567 
   6568 /**
   6569  * push element to array (only increases last)
   6570  * use staticArrayLast to access the element
   6571  */
   6572 #define indexerPush staticArrayPush
   6573 #define indexerPPush ringPush
   6574 
   6575 /**
   6576  * pop element from array (only decreases last)
   6577  */
   6578 #define indexerPop staticArrayPop
   6579 #define indexerPPop ringPop
   6580 
   6581 /**
   6582  * prepend element to array (only decreases head)
   6583  * use staticArrayFirst to access the element
   6584  */
   6585 #define indexerPrepend staticArrayPrepend
   6586 #define indexerPPrepend ringPrepend
   6587 
   6588 /**
   6589  * dequeue element from array (only increases head)
   6590  */
   6591 #define indexerDequeue staticArrayDequeue
   6592 #define indexerPDequeue ringDequeue
   6593 
   6594 /**
   6595  * index element at index with name->head index 0, negative index is supported
   6596  */
   6597 #define indexerRef(name, index) (((((index) >= 0) ? (index) : indexerCount(name) + (index) ) + name.head) % name.maxCount)
   6598 #define indexerPRef(name, index) (((((index) >= 0) ? (index) : indexerPCount(name) + (index) ) + name->head) % name->maxCount)
   6599 
   6600 /**
   6601  * index of last element in array
   6602  */
   6603 #define indexerLast(name) name.last
   6604 #define indexerPLast(name) (name)->last
   6605 
   6606 /**
   6607  * index of first element in array
   6608  */
   6609 #define indexerFirst(name) (name.head)
   6610 #define indexerPFirst(name) (name)->head
   6611 
   6612 
   6613 /**
   6614  * rings usage
   6615  *
   6616  * Make the ring type:
   6617  *
   6618  *   #define chanMax 30                // max message count in ring type chanT
   6619  *   ringMake(chanT, int, chanMax); // ring type is chanT, list 30 of ints
   6620  *
   6621  * Add ring to a fiber context:
   6622  *
   6623  *   typedef struct {int slot; int a; chanT *c;} AArgs;
   6624  *
   6625  * Declare a ring of type chanT and initialize:
   6626  *
   6627  *   chanT c;
   6628  *   ringInit(&c, chanMax);
   6629  *
   6630  * When the ring is empty, ringLast and ringFirst are valid and equal (same index).
   6631  *
   6632  * Send and receive data through the ring:
   6633  *
   6634  *   ringSend(ctx->c, 10);
   6635  *   int r;
   6636  *   if (!ringIsEmpty(ctx->c))
   6637  *     ringRecv(ctx->c, r);
   6638  *
   6639  * Note: some functions are macros to be able to have structs as element and
   6640  *       access the struct members directly, for example:
   6641  *         ringLast(chan).a = 0;
   6642  *
   6643  */
   6644 /**
   6645  * base type, same as staticArray
   6646  */
   6647 #define ringBase staticArrayBase
   6648 
   6649 /**
   6650  * declares type for staticArray or ring
   6651  * staticArrayT(typeName, element, MAXCOUNT)
   6652  *
   6653  * \param
   6654  * typeName staticArray/ring type name
   6655  * \param
   6656  * element type of elements (int, struct, pointer...)
   6657  * \pointer
   6658  * MAXCOUNT array/ring buffer size
   6659  */
   6660 #define ringMake staticArrayT
   6661 
   6662 /**
   6663  * initialize count in array/static ring
   6664  * staticArrayInit(name, MAXCOUNT)
   6665  *
   6666  * this macro can initialize rings if the struct is accessed directly
   6667  *
   6668  * \param
   6669  * name variable name for ring
   6670  */
   6671 #define ringStaticInit staticArrayInit
   6672 
   6673 // initialize ring/pointer to staticArray
   6674 int ringInit(void *ring, int maxCount);
   6675 
   6676 // empty ring
   6677 int ringEmpty(void *ring);
   6678 
   6679 // is ring Empty
   6680 int ringIsEmpty(void *ring);
   6681 
   6682 // is ring Full
   6683 int ringIsFull(void *ring);
   6684 
   6685 // return elements count
   6686 ssize_t ringCount(void *ring);
   6687 
   6688 
   6689 // push element to ring (only increases last, use ringSend), use ringLast to access the element
   6690 i64 ringPush(void *ring);
   6691 
   6692 
   6693 // pop element from ring (only decreases last)
   6694 int ringPop(void *ring);
   6695 
   6696 
   6697 // prepend element to ring (only decreases head), use ringFirst to access the element
   6698 i64 ringPrepend(void *ring);
   6699 
   6700 // dequeue element from ring (only increases head, use ringRecv)
   6701 int ringDequeue(void *ring);
   6702 
   6703 /**
   6704  * get element at index, negative index is supported
   6705  */
   6706 #define ringGet(name, index) (name)->list[(((index) >= 0) ? (index) : ringCount(name) + (index) )]
   6707 
   6708 /**
   6709  * get element at index with name->head index 0, negative index is supported
   6710  */
   6711 #define ringRef(name, index) (name)->list[((((index) >= 0) ? (index) : ringCount(name) + (index) ) + name->head) % name->maxCount]
   6712 
   6713 /**
   6714  * last element in ring
   6715  */
   6716 #define ringLast(name) (name)->list[(name)->last]
   6717 
   6718 /**
   6719  * index of last element
   6720  */
   6721 #define ringLastIndex(name) (name)->last
   6722 
   6723 /**
   6724  * last element in ring
   6725  */
   6726 #define ringFirst(name) (name)->list[(name)->head]
   6727 
   6728 
   6729 /**
   6730  * send data in ring
   6731  *
   6732  * \param
   6733  * name variable name for ring
   6734  * \param
   6735  * value data
   6736  */
   6737 #define ringSend(name, value)\
   6738   do {\
   6739     if (ringPush(name) >= 0) ringLast(name) = value;\
   6740   } while(0);
   6741 
   6742 // send data and get ring status
   6743 #define ringSendSt(status, name, value)\
   6744   do {\
   6745     if ((status = ringPush(name)) >= 0) ringLast(name) = value;\
   6746   } while(0);
   6747 
   6748 
   6749 /**
   6750  * receive data from ring
   6751  *
   6752  * \param
   6753  * name variable name for ring
   6754  * \param
   6755  * result previously declared variable to store the data
   6756  */
   6757 #define ringRecv(name, result)\
   6758   do {\
   6759     result = ringFirst(name);\
   6760     ringDequeue(name);\
   6761   } while(0);
   6762 
   6763 // receive data and get ring status
   6764 #define ringRecvSt(status, name, result)\
   6765   do {\
   6766     if ((status = ringIsEmpty(name)) == 0) {\
   6767       result = ringFirst(name);\
   6768       ringDequeue(name);\
   6769     }\
   6770   } while(0);
   6771 
   6772 /**
   6773  * fiber usage
   6774  *
   6775  * The stack is not restored, so all local variables should
   6776  * be stored in the context struct.
   6777  *
   6778  * Declare a context type for the fiber:
   6779  *
   6780  *   typedef struct {int slot; int a; chanT *c;} AArgs;
   6781  *
   6782  * the context type must start with int slot;
   6783  * in this example, the fiber has a ring c of type chanT
   6784  *
   6785  * Declare a function of type:
   6786  *
   6787  *   void fiberA(int thisSlot) {
   6788  *     static AArgs *ctx;
   6789  *     int slot;
   6790  *     ctx = fiberCtx(thisSlot);
   6791  *     ...
   6792  *   }
   6793  *
   6794  * several fibers can have the function fiberA with different slots
   6795  *
   6796  * To yield, add:
   6797  *
   6798  *   yield(slot, ctx->slot); // switch to scheduler
   6799  *   ctx = fiberCtx(slot);   // restore the context for this fiber
   6800  *
   6801  * The next steps show how to start the fibers
   6802  *
   6803  * Declare a variable for the context and create the ring chanT:
   6804  *
   6805  *   AArgs Aa;
   6806  *   chanT c;
   6807  *   ringInit(&c, chanMax);
   6808  *
   6809  * Initialize the fiber:
   6810  *
   6811  *   Aa.a = 0;
   6812  *   Aa.c = &c;
   6813  *   fiberAdd(&Aa, 1, fiberA);
   6814  *
   6815  * this can also be done from a running fiber
   6816  *
   6817  * Finally, start the scheduler:
   6818  *
   6819  *   scheduler();
   6820  *
   6821  */
   6822 
   6823 // schedule fibers
   6824 void scheduler(void);
   6825 
   6826 // the scheduler takes slot 0
   6827 // the system can handle tCount-1 fibers
   6828 #define tCount 10
   6829 
   6830 /**
   6831  * all contexts must start with fiberBaseT
   6832  *
   6833  * Example:
   6834  * typedef struct {int slot; int a;} AArgs;
   6835  */
   6836 typedef struct {int slot;} fiberBaseT;
   6837 
   6838 /**
   6839  * staticArray to hold the fiber slots
   6840  */
   6841 staticArrayT(fiberLT, int, tCount);
   6842 
   6843 /**
   6844  * data type for fiber system
   6845  */
   6846 typedef struct {
   6847   /**
   6848    * setjmp buffers for fibers
   6849    */
   6850   jmp_buf jumpBuffers[tCount];
   6851   /**
   6852    * running fibers
   6853    */
   6854   fiberLT L;
   6855   /**
   6856    * fibers to start
   6857    */
   6858   fiberLT startL;
   6859   /**
   6860    * fiber context data
   6861    */
   6862   void *context[tCount];
   6863   /**
   6864    * fiber functions
   6865    */
   6866   void (*F[tCount])(int thisSlot);
   6867 } fibersT;
   6868 
   6869 /**
   6870  * data for fiber system
   6871  */
   6872 extern fibersT fibers;
   6873 
   6874 /**
   6875  * get fiber context for thisSlot
   6876  */
   6877 #define fiberCtx(thisSlot) fibers.context[thisSlot]
   6878 
   6879 /**
   6880  * fiber function type
   6881  */
   6882 typedef void (*fiberFT)(int);
   6883 
   6884 /**
   6885  * add new fiber
   6886  */
   6887 bool fiberAdd(void *ctx, int thisSlot, fiberFT func);
   6888 
   6889 /**
   6890  * add new fiber and start immediately after next yield
   6891  */
   6892 bool fiberPrepend(void *ctx, int thisSlot, fiberFT func);
   6893 
   6894 /**
   6895  * fibers with setjmp (not ucontext)
   6896  * internal
   6897  *
   6898  * startJump starts another fiber
   6899  * slot is the index in fiberJumpBuffers for current fiber
   6900  * func is the fiber to start
   6901  *
   6902  * the first fiber has to finish last
   6903  */
   6904 #define startJump(func)\
   6905   if (!setjmp(fibers.jumpBuffers[0])) {\
   6906       func;\
   6907   }
   6908 
   6909 #if !__sun__
   6910 /**
   6911  * yield jumps back to other fiber
   6912  * slot should be a local variable in the fiber
   6913  * slot is set to the index in fiberJumpBuffers for current fiber
   6914  * backToSlot is the index in fiberJumpBuffers for the other fiber
   6915  */
   6916 #define yield(slotValue, slot)\
   6917   if (!(slotValue = setjmp(fibers.jumpBuffers[slot]))) {\
   6918     staticArrayPush(fibers.L);\
   6919     staticArrayLast(fibers.L) = slot;\
   6920     longjmp(fibers.jumpBuffers[0], 1);\
   6921   }
   6922 #endif
   6923 
   6924 /**
   6925  * return to scheduler and end the fiber
   6926  */
   6927 #define fiberEnd(slot)\
   6928   if (!setjmp(fibers.jumpBuffers[slot])) {\
   6929     longjmp(fibers.jumpBuffers[0], 1);\
   6930   }
   6931 
   6932 // internal for scheduler
   6933 #define schedulerYield(backToSlot)\
   6934   if (!setjmp(fibers.jumpBuffers[0])) {\
   6935     longjmp(fibers.jumpBuffers[backToSlot], backToSlot);\
   6936   }
   6937 
   6938 
   6939 
   6940 /**
   6941  * dynamic segmented array
   6942  *
   6943  * this type of array is faster than slab when there are many elements and has a dynamic element count
   6944  * pushing elements into the array increases the element count
   6945  * the data is stored in static array segments
   6946  * dArray has head and last indexes, this allows dequeuing from head elements fast
   6947  *
   6948  * no sanity checks are done
   6949  *
   6950  * usage examples: regular array, stack, lifo, fifo
   6951  *
   6952  * the prefix is dArray
   6953  *
   6954  * Usage:
   6955  *
   6956  * to declare an array:
   6957  *
   6958  * dArrayT(typeName, type);
   6959  *
   6960  * typeName darray;
   6961  *
   6962  * dArrayInit(&darray);
   6963  * or
   6964  * dArrayInitCount(&darray, 17);
   6965  *
   6966  * dArrayAppend(&darray, value);
   6967  *
   6968  * // get an element
   6969  * int a                = dArrayAt(&darray, 0);
   6970  *
   6971  * set
   6972  * dArrayAt(&darray, 1) = 3;
   6973  *
   6974  * dArrayFree(&darray);
   6975  *
   6976  * dArray variables:
   6977  * darray.maxCount: maximum element count allowed
   6978  *
   6979  * Note: dont combine the macros, it gives wrong results:
   6980  *       a = dArrayAt(&darray, dArrayPop(&darray2));
   6981  *       dArrayPop is run several time, more than one element is popped
   6982  *
   6983  * Note: some functions are macros to be able to have structs as element and
   6984  *       access the struct members directly, for example:
   6985  *         dArrayLast(chan).a = 0;
   6986  */
   6987 
   6988 // user parameters
   6989 /**
   6990  * chunk size: 2^dArrayBits elements
   6991  */
   6992 #define dArrayBits 6
   6993 // user parameters end
   6994 
   6995 #define dArraySz   (1<<dArrayBits)
   6996 #define dArrayMask (dArraySz-1)
   6997 
   6998 /**
   6999  * declares type for dynamic array
   7000  *
   7001  * \param
   7002  * typeName dArray type name
   7003  * \param
   7004  * element type of elements (int, struct, pointer...)
   7005  */
   7006 #define dArrayT(typeName, elementType)\
   7007   typedef struct {\
   7008     int64_t    last;\
   7009     int64_t    head;\
   7010     int64_t    maxCount;\
   7011     void**      buffers;\
   7012     elementType element;\
   7013   } typeName
   7014 
   7015 
   7016 #define createDArray(typeName, name) ;typeName name; dArrayInit(&name)
   7017 
   7018 #define createDArrayCount(typeName, name, count) ;typeName name; dArrayInitCount(&name, count)
   7019 
   7020 /**
   7021  * initialize dynamic array with minimum element count
   7022  *
   7023  * \param
   7024  * a variable name for dArray
   7025  */
   7026 #define dArrayInit(a) do{\
   7027     (a)->last = (a)->head = 0;\
   7028     (a)->buffers          = malloc(sizeof(void*));\
   7029     (a)->buffers[0]       = malloc(dArraySz * sizeof((a)->element));\
   7030     (a)->maxCount         = 1;\
   7031   }while(0)
   7032 
   7033 /**
   7034  * initialize dynamic array and count
   7035  *
   7036  * \param
   7037  * a variable name for dArray
   7038  * \param
   7039  * count initial element count for name type
   7040  */
   7041 #define dArrayInitCount(a, count) do{\
   7042     dArrayInit(a);\
   7043     if ((count) > dArraySz) {\
   7044       (a)->buffers = realloc((a)->buffers, (((count)>>dArrayBits)+1) * sizeof(void*));\
   7045       rangeFrom(UNIQVAR(i), 1, ((count)>>dArrayBits)+1) {\
   7046         (a)->buffers[UNIQVAR(i)] = malloc(dArraySz * sizeof((a)->element));\
   7047       }\
   7048       (a)->maxCount = ((count)>>dArrayBits)+1;\
   7049     }\
   7050   }while(0)
   7051 
   7052 #define dArrayResize(a, count) do{\
   7053     if ((count) > (a)->maxCount * dArraySz) {\
   7054       /* grow array */\
   7055       (a)->buffers = realloc((a)->buffers, (((count)>>dArrayBits)+1) * sizeof(void*));\
   7056       rangeFrom(UNIQVAR(i), (a)->maxCount, ((count)>>dArrayBits)+1) {\
   7057         (a)->buffers[UNIQVAR(i)] = malloc(dArraySz * sizeof((a)->element));\
   7058       }\
   7059       (a)->maxCount = ((count)>>dArrayBits)+1;\
   7060     }\
   7061     /*else TODO dArray shrink */\
   7062   }while(0)
   7063 
   7064 /**
   7065  * free the internal buffers
   7066  *
   7067  * \param
   7068  * a dynamic array
   7069  */
   7070 #define dArrayFree dVectorFree
   7071 
   7072 /**
   7073  * element type in array
   7074  */
   7075 #define dArrayElemType(a) typeof((a)->element)
   7076 
   7077 /**
   7078  * element pointer type in array
   7079  */
   7080 #define dArrayElemPtrType(a) typeof(&(a)->element)
   7081 
   7082 /**
   7083  * Empty Array
   7084  * Allocated buffers in the array must be freed before running dArrayEmpty
   7085  */
   7086 #define dArrayEmpty(name) do{\
   7087     (name)->last = (name)->head = 0;\
   7088   } while(0);
   7089 
   7090 /**
   7091  * is Array Empty
   7092  */
   7093 #define dArrayIsEmpty(name) ((name)->head == (name)->last)
   7094 
   7095 /**
   7096  * return element count
   7097  */
   7098 #define dArrayCount(name) ((name)->last - (name)->head)
   7099 
   7100 /**
   7101  * return max element count
   7102  */
   7103 #define dArrayMaxCount(name) ((name)->maxCount * dArraySz)
   7104 
   7105 /**
   7106  * allocate buffer for new elements
   7107  * only when the array is full
   7108  *
   7109  * \param
   7110  * a dynamic array
   7111  */
   7112 #define dArrayAlloc(a) do{\
   7113     if ((a)->last == dArrayMaxCount(a)) {\
   7114       (a)->maxCount++;\
   7115       (a)->buffers = realloc((a)->buffers, (size_t)(a)->maxCount * sizeof(void*));\
   7116       (a)->buffers[(a)->maxCount-1] = malloc(dArraySz * sizeof((a)->element));\
   7117     }\
   7118   }while(0)
   7119 
   7120 /**
   7121  * push element and expand the dynamic array
   7122  * no data (random) is set in the new element.
   7123  *
   7124  * \param
   7125  * a dynamic array
   7126  * \param
   7127  * v element to push
   7128  */
   7129 #define dArrayPush(a) do{\
   7130     dArrayAlloc(a);\
   7131     (a)->last++;\
   7132   }while(0)
   7133 
   7134 /**
   7135  * append element and expand the dynamic array
   7136  *
   7137  * \param
   7138  * a dynamic array
   7139  * \param
   7140  * v element to push
   7141  */
   7142 #define dArrayAppend(a, v) do{\
   7143     dArrayAlloc(a);\
   7144     if ((a)->last < dArrayMaxCount(a)) {\
   7145       typeof((a)->element) *UNIQVAR(buffer) = (a)->buffers[((a)->last)>>dArrayBits];\
   7146       *(UNIQVAR(buffer)+ (((a)->last)&dArrayMask)) = v;\
   7147       (a)->last++;\
   7148     }\
   7149   }while(0)
   7150 
   7151 /**
   7152  * pop element
   7153  * the index of the last element is decreased
   7154  *
   7155  * NOTE: using comma operator to avoid warning
   7156  * warning: operation on ‘b.head’ may be undefined [-Wsequence-point]
   7157  *
   7158  *
   7159  * \param
   7160  * a dynamic array
   7161  */
   7162 #define dArrayPop(a) ((a)->last--, *((typeof((a)->element)*)((a)->buffers[((a)->last)>>dArrayBits])+(((a)->last)&dArrayMask)))
   7163 
   7164 /**
   7165  * delete the last element
   7166  * useful for avoiding warning: right-hand operand of comma expression has no effect
   7167  * when the poped value is not used
   7168  */
   7169 #define dArrayDelLast(a) ((a)->last--)
   7170 
   7171 /**
   7172  * prepend element
   7173  *
   7174  * \param
   7175  * a dynamic array
   7176  * \param
   7177  * v element to prepend
   7178  */
   7179 #define dArrayPrepend(a, v) do{\
   7180     if ((a)->head > 0) {\
   7181       (a)->head--;\
   7182       typeof((a)->element) *UNIQVAR(buffer) = (a)->buffers[((a)->head)>>dArrayBits];\
   7183       *(UNIQVAR(buffer)+ (((a)->head)&dArrayMask)) = v;\
   7184     }\
   7185   }while(0)
   7186 
   7187 /**
   7188  * dequeue element
   7189  * the index of the head element is increased
   7190  *
   7191  * NOTE: using comma operator to avoid warning
   7192  * warning: operation on ‘b.head’ may be undefined [-Wsequence-point]
   7193  *
   7194  *
   7195  * \param
   7196  * a dynamic array
   7197  */
   7198 #define dArrayDequeue(a) ((a)->head++, *((typeof((a)->element)*)((a)->buffers[((a)->head-1)>>dArrayBits])+(((a)->head-1)&dArrayMask)))
   7199 
   7200 /**
   7201  * delete the first element
   7202  * useful for avoiding warning: right-hand operand of comma expression has no effect
   7203  * when the dequeued value is not used
   7204  */
   7205 #define dArrayDelFirst(a) ((a)->head++)
   7206 
   7207 /**
   7208  * get / set element at index
   7209  *
   7210  * \param
   7211  * a dynamic array
   7212  * \param
   7213  * index index in array
   7214  */
   7215 #define dArrayAt(a, index) (*((typeof((a)->element)*)((a)->buffers[(index)>>dArrayBits])+((index)&dArrayMask)))
   7216 
   7217 /**
   7218  * get pointer to element at index
   7219  *
   7220  * \param
   7221  * a dynamic array
   7222  * \param
   7223  * index index in array
   7224  */
   7225 #define dArrayPtr(a, index) ((typeof((a)->element)*)((a)->buffers[(index)>>dArrayBits])+((index)&dArrayMask))
   7226 
   7227 /**
   7228  * set at index and resize dArray when index is greater then maxCount
   7229  */
   7230 #define dArraySet(a, index, v) do{\
   7231   var UNIQVAR(idx) = index;\
   7232   if (UNIQVAR(idx) < (a)->last) {\
   7233     /* index is inside current array */\
   7234     dArrayAt(a, UNIQVAR(idx)) = v;\
   7235     if (UNIQVAR(idx) < (a)->head) {\
   7236       /* update head since index is lower */\
   7237       (a)->head = UNIQVAR(idx);\
   7238     }\
   7239   }\
   7240   else {\
   7241     /* index is after last element */\
   7242     /* check if index is under maxCount */\
   7243     if (UNIQVAR(idx) >= dArrayMaxCount(a)) {\
   7244       /* resize array */\
   7245       dArrayResize(a, UNIQVAR(idx)+1);\
   7246     }\
   7247     dArrayAt(a, UNIQVAR(idx)) = v;\
   7248     /* update last since index is higher*/\
   7249     (a)->last = UNIQVAR(idx)+1;\
   7250   }\
   7251   }while(0)
   7252 
   7253 /**
   7254  * sparse set at index and resize dArray when index is greater then maxCount
   7255  * dArraySparseSet allows using dArray as a sparse array
   7256  *
   7257  * head and last are not updated because there are empty regions in the sparse array
   7258  *
   7259  * the empty segments are marked with NULL in the a->buffers array
   7260  *
   7261  * after using dArraySparseSet only these macros are valid:
   7262  * dArrayResize, dArrayElemType, dArrayElemPtrType, dArrayMaxCount, dArrayAt, dArrayPtr, dArrayFree
   7263  */
   7264 #define dArraySparseSet(a, index, v) do{\
   7265   var UNIQVAR(idx)     = index;\
   7266   var UNIQVAR(bIdx)    = UNIQVAR(idx)>>dArrayBits;\
   7267   if (UNIQVAR(idx) >= dArrayMaxCount(a)) {\
   7268     /* sparse resize array - grow array */\
   7269     (a)->buffers = realloc((a)->buffers, (((UNIQVAR(bIdx)+1)>>dArrayBits)+1) * sizeof(void*));\
   7270     /* empty segments are marked with NULL */\
   7271     memset(&(a)->buffers[(a)->maxCount], 0, (UNIQVAR(bIdx)+1) - (a)->maxCount);\
   7272     (a)->maxCount = UNIQVAR(bIdx)+1;\
   7273     /* allocate new segment */\
   7274     (a)->buffers[UNIQVAR(bIdx)] = malloc(dArraySz * sizeof((a)->element));\
   7275     dArrayAt(a, UNIQVAR(idx)) = v;\
   7276   }\
   7277   else {\
   7278     /* check if the segment is already allocated */\
   7279     if (!(a)->buffers[UNIQVAR(bIdx)]) {\
   7280       /* allocate new segment */\
   7281       (a)->buffers[UNIQVAR(bIdx)] = malloc(dArraySz * sizeof((a)->element));\
   7282     }\
   7283     dArrayAt(a, UNIQVAR(idx)) = v;\
   7284   }\
   7285   }while(0)
   7286 
   7287 /**
   7288  * last element
   7289  *
   7290  * \param
   7291  * a dynamic array
   7292  */
   7293 #define dArrayLast(a) (*((typeof((a)->element)*)((a)->buffers[((a)->last-1)>>dArrayBits])+(((a)->last-1)&dArrayMask)))
   7294 
   7295 /**
   7296  * pointer to last element
   7297  *
   7298  * \param
   7299  * a dynamic array
   7300  */
   7301 #define dArrayLastPtr(a) ((typeof((a)->element)*)((a)->buffers[((a)->last-1)>>dArrayBits])+(((a)->last-1)&dArrayMask))
   7302 
   7303 /**
   7304  * index of last element
   7305  */
   7306 #define dArrayLastIndex(a) ((a)->last-1)
   7307 
   7308 /**
   7309  * direct access to the last element index variable for assignments
   7310  */
   7311 #define dArrayLastIndexVar(a) ((a)->last)
   7312 
   7313 /**
   7314  * first element
   7315  *
   7316  * \param
   7317  * a dynamic array
   7318  */
   7319 #define dArrayFirst(a) (*((typeof((a)->element)*)((a)->buffers[((a)->head)>>dArrayBits])+((a)->head)&dArrayMask))
   7320 
   7321 /**
   7322  * index of first element
   7323  */
   7324 #define dArrayFirstIndex(a) ((a)->head)
   7325 
   7326 /**
   7327  * write the dArray content to filename file
   7328  * No NULL checks are done on the parameters
   7329  *
   7330  * \param
   7331  *    filename file name string
   7332  */
   7333 #define dArrayWriteFilename(a, filename) do {\
   7334     FILE *UNIQVAR(f) = fopen(filename, "w");\
   7335     if (UNIQVAR(f)) {\
   7336       range(UNIQVAR(i), (size_t)dArrayCount(a)) {\
   7337         typeof((a)->element) *firstElement = (a)->buffers[UNIQVAR(i)/dArraySz];\
   7338         fwrite(firstElement+(UNIQVAR(i)%dArraySz), 1, sizeof((a)->element), UNIQVAR(f));\
   7339       }\
   7340       fclose(UNIQVAR(f));\
   7341     }\
   7342   } while(0)
   7343 
   7344 /**
   7345  * write the dArray content to disk
   7346  * No NULL checks are done on the parameters
   7347  *
   7348  * \param
   7349  *    file already opened file
   7350  */
   7351 #define dArrayWrite(a, file) do {\
   7352     range(UNIQVAR(i), (size_t)dArrayCount(a)) {\
   7353       typeof((a)->element) *firstElement = (a)->buffers[UNIQVAR(i)/dArraySz];\
   7354       fwrite(firstElement+(UNIQVAR(i)%dArraySz), 1, sizeof((a)->element), file);\
   7355     }\
   7356   } while(0)
   7357 
   7358 /**
   7359  * read a dArray from filename file
   7360  * No NULL checks are done on the parameters
   7361  *
   7362  * \param
   7363  * filename file name string
   7364  */
   7365 #define dArrayReadFilename(a, filename) do {\
   7366     if (fileExists(filename)) {\
   7367       size_t UNIQVAR(sz) = fileSize(filename);\
   7368       FILE *UNIQVAR(f) = fopen(filename, "r");\
   7369       if (UNIQVAR(f)) {\
   7370         range(UNIQVAR(i), UNIQVAR(sz)/sizeof((a)->element)) {\
   7371           dArrayPush(a);\
   7372           fread(dArrayLastPtr(a), 1, sizeof((a)->element), UNIQVAR(f));\
   7373         }\
   7374         fclose(UNIQVAR(f));\
   7375       }\
   7376     }\
   7377   } while(0)
   7378 
   7379 /**
   7380  * read a dArray from disk
   7381  * No NULL checks are done on the parameters
   7382  *
   7383  * \param
   7384  *    file already opened file
   7385  */
   7386 #define dArrayRead(a, file) do {\
   7387     fseek(file, 0 , SEEK_END);\
   7388     size_t UNIQVAR(sz) = ftell(file);\
   7389     fseek(file, 0 , SEEK_SET);\
   7390     range(UNIQVAR(i), UNIQVAR(sz)/sizeof((a)->element)) {\
   7391       dArrayPush(a);\
   7392       fread(dArrayLastPtr(a), 1, sizeof((a)->element), file);\
   7393     }\
   7394   } while(0)
   7395 
   7396 /**
   7397  * loop on dArray elements
   7398  * element is a pointer to a value in the array
   7399  *
   7400  * dArrayForEach(&a, e) {
   7401  *    e->x = 0;
   7402  * }
   7403  */
   7404 #define dArrayForEach(name, element) \
   7405   ;size_t UNIQVAR(libsheepyInternalIndex) = (name)->head; \
   7406   for (dArrayElemPtrType(name) element = dArrayPtr(name, (name)->head) ; UNIQVAR(libsheepyInternalIndex) < (name)->last + 1 ; UNIQVAR(libsheepyInternalIndex)++, element = dArrayPtr(name, UNIQVAR(libsheepyInternalIndex)))
   7407 
   7408 /**
   7409  * enumerate dArray elements
   7410  * index is the position of the element in the array
   7411  * index is declared as size_t and is available after the loop
   7412  * element is a pointer to a value in the array
   7413  *
   7414  * dArrayEnumerate(&a, i, e) {
   7415  *    e->x = 0;
   7416  *    printf("dArrayEnumerate %d\n", i);
   7417  * }
   7418  */
   7419 #define dArrayEnumerate(name, index, element) \
   7420   ; size_t index = (name)->head; \
   7421   for (dArrayElemPtrType(name) element = dArrayPtr(name, (name)->head) ; index < (name)->last + 1 ; index++, element = dArrayPtr(name, index))
   7422 
   7423 
   7424 
   7425 /*
   7426  * end dynamic array
   7427  */
   7428 
   7429 
   7430 /**
   7431  * slab - dynamic array in one chunk of memory
   7432  *
   7433  * slab supports shrinking through slabResize, the slab is reset when head or last are outside the new size
   7434  * slab has head and last indexes, this allows dequeuing from head elements fast
   7435  *
   7436  * this type of array has a dynamic element count
   7437  * pushing elements into the array increases the element count
   7438  *
   7439  * no sanity checks are done
   7440  *
   7441  * usage examples: regular array, stack, lifo, fifo
   7442  *
   7443  * the prefix is slab
   7444  *
   7445  * Usage:
   7446  *
   7447  * to declare an array:
   7448  *
   7449  * slabT(typeName, type);
   7450  *
   7451  * typeName slab;
   7452  *
   7453  * slabInit(&slab);
   7454  * or
   7455  * slabInitCount(&slab, 17);
   7456  *
   7457  * slabAppend(&slab, value);
   7458  *
   7459  * // get an element
   7460  * int a                = slabAt(&slab, 0);
   7461  *
   7462  * set
   7463  * slabAt(&slab, 1) = 3;
   7464  *
   7465  * slabFree(&slab);
   7466  *
   7467  * Slab variables:
   7468  * slab.array:     elements
   7469  * slab.maxCount:  maximum element count allowed
   7470  *
   7471  * Note: some functions are macros to be able to have structs as element and
   7472  *       access the struct members directly, for example:
   7473  *         slabLast(chan).a = 0;
   7474  */
   7475 
   7476 /** number of elements added by slabAlloc */
   7477 #define slabSz 64
   7478 
   7479 /**
   7480  * declares type for dynamic array
   7481  *
   7482  * \param
   7483  * typeName slab type name
   7484  * \param
   7485  * element type of elements (int, struct, pointer...)
   7486  */
   7487 #define slabT(typeName, elementType)\
   7488   typedef struct {\
   7489     int64_t      last;\
   7490     int64_t      head;\
   7491     int64_t      maxCount;\
   7492     elementType *array;\
   7493   } typeName
   7494 
   7495 
   7496 #define createSlab(typeName, name) ;typeName name; slabInit(&name)
   7497 
   7498 #define createSlabCount(typeName, name, count) ;typeName name; slabInitCount(&name, count)
   7499 
   7500 /**
   7501  * initialize dynamic array with minimum element count
   7502  *
   7503  * \param
   7504  * a variable name for slab
   7505  */
   7506 #define slabInit(a) do{\
   7507     (a)->last = (a)->head = 0;\
   7508     (a)->array            = malloc(sizeof(*((a)->array)) * slabSz);\
   7509     (a)->maxCount         = slabSz;\
   7510   }while(0)
   7511 
   7512 
   7513 /**
   7514  * initialize slab and count
   7515  *
   7516  * \param
   7517  * a variable name for slab
   7518  * \param
   7519  * count initial element count for name type
   7520  */
   7521 #define slabInitCount(a, count) do{\
   7522     var UNIQVAR(c)        = count;\
   7523     (a)->last = (a)->head = 0;\
   7524     (a)->array            = malloc(sizeof(*((a)->array)) * UNIQVAR(c));\
   7525     (a)->maxCount         = UNIQVAR(c);\
   7526   }while(0)
   7527 
   7528 #define slabResize(a, count) do{\
   7529     var UNIQVAR(c)        = count;\
   7530     (a)->array            = realloc((a)->array, sizeof(*((a)->array)) * UNIQVAR(c));\
   7531     (a)->maxCount         = UNIQVAR(c);\
   7532     if (((a)->last >= (a)->maxCount) || ((a)->head >= (a)->maxCount)) {\
   7533       /* shrinking error - head or last outside the new array, reset to 0 */\
   7534       (a)->last = (a)->head = 0;\
   7535     }\
   7536   }while(0)
   7537 
   7538 /**
   7539  * free the internal buffers
   7540  *
   7541  * \param
   7542  * a slab
   7543  */
   7544 #define slabFree sliceFree
   7545 
   7546 /**
   7547  * element type in array
   7548  */
   7549 #define slabElemType(name) typeof((name)->array[0])
   7550 
   7551 /**
   7552  * element pointer type in array
   7553  */
   7554 #define slabElemPtrType(name) typeof(&(name)->array[0])
   7555 
   7556 /**
   7557  * Empty Array
   7558  */
   7559 #define slabEmpty(name) do{\
   7560     (name)->last = (name)->head = 0;\
   7561   } while(0);
   7562 
   7563 /**
   7564  * is Array Empty
   7565  */
   7566 #define slabIsEmpty(name) ((name)->head == (name)->last)
   7567 
   7568 /**
   7569  * return element count
   7570  */
   7571 #define slabCount(name) ((name)->last - (name)->head)
   7572 
   7573 /**
   7574  * return max element count
   7575  */
   7576 #define slabMaxCount vectorMaxCount
   7577 
   7578 /**
   7579  * allocate buffer for new elements
   7580  * only when the slab is full
   7581  *
   7582  * \param
   7583  * a dynamic array
   7584  */
   7585 #define slabAlloc(a) do{\
   7586     if ((a)->last == slabMaxCount(a)) {\
   7587       (a)->maxCount += slabSz;\
   7588       slabResize(a, (a)->maxCount);\
   7589     }\
   7590   }while(0)
   7591 
   7592 /**
   7593  * push element and expand the slab
   7594  * no data (random) is set in the new element
   7595  *
   7596  * \param
   7597  * a slab
   7598  */
   7599 #define slabPush(a) do{\
   7600     slabAlloc(a);\
   7601     (a)->last++;\
   7602   }while(0)
   7603 
   7604 /**
   7605  * append element and expand the slab
   7606  *
   7607  * \param
   7608  * a slab
   7609  * \param
   7610  * v element to push
   7611  */
   7612 #define slabAppend(a, v) do{\
   7613     slabAlloc(a);\
   7614     if ((a)->last < slabMaxCount(a)) {\
   7615       *( (a)->array + (a)->last ) = v;\
   7616       (a)->last++;\
   7617     }\
   7618   }while(0)
   7619 
   7620 /**
   7621  * pop element
   7622  * the index of the last element is decreased
   7623  *
   7624  * NOTE: using comma operator to avoid warning
   7625  * warning: operation on ‘b.head’ may be undefined [-Wsequence-point]
   7626  *
   7627  *
   7628  * \param
   7629  * a slab
   7630  */
   7631 #define slabPop(a) ((a)->last--, *((a)->array + (a)->last))
   7632 
   7633 /**
   7634  * delete the last element
   7635  * useful for avoiding warning: right-hand operand of comma expression has no effect
   7636  * when the poped value is not used
   7637  */
   7638 #define slabDelLast(a) ((a)->last--)
   7639 
   7640 /**
   7641  * prepend element
   7642  *
   7643  * \param
   7644  * a slab
   7645  * \param
   7646  * v element to prepend
   7647  */
   7648 #define slabPrepend(a, v) do{\
   7649     if ((a)->head > 0) {\
   7650       (a)->head--;\
   7651       *( (a)->array + (a)->head ) = v;\
   7652     }\
   7653   }while(0)
   7654 
   7655 /**
   7656  * dequeue element
   7657  * the index of the head element is increased
   7658  *
   7659  * NOTE: using comma operator to avoid warning
   7660  * warning: operation on ‘b.head’ may be undefined [-Wsequence-point]
   7661  *
   7662  *
   7663  * \param
   7664  * a slab
   7665  */
   7666 #define slabDequeue(a) ((a)->head++, *((a)->array + (a)->head -1))
   7667 
   7668 /**
   7669  * delete the first element
   7670  * useful for avoiding warning: right-hand operand of comma expression has no effect
   7671  * when the dequeued value is not used
   7672  */
   7673 #define slabDelFirst(a) ((a)->head++)
   7674 
   7675 /**
   7676  * get / set element at index
   7677  *
   7678  * \param
   7679  * a slab
   7680  * \param
   7681  * index index in array
   7682  */
   7683 #define slabAt sliceAt
   7684 
   7685 /**
   7686  * get pointer to element at index
   7687  *
   7688  * \param
   7689  * a slab
   7690  * \param
   7691  * index index in array
   7692  */
   7693 #define slabPtr slicePtr
   7694 
   7695 /**
   7696  * last element
   7697  *
   7698  * \param
   7699  * a slab
   7700  */
   7701 #define slabLast(a) (*((a)->array + (a)->last -1))
   7702 
   7703 /**
   7704  * pointer to last element
   7705  *
   7706  * \param
   7707  * a slab
   7708  */
   7709 #define slabLastPtr(a) ((a)->array + (a)->last -1)
   7710 
   7711 /**
   7712  * index of last element
   7713  */
   7714 #define slabLastIndex(a) ((a)->last-1)
   7715 
   7716 /**
   7717  * direct access to the last element index variable for assignments
   7718  */
   7719 #define slabLastIndexVar(a) ((a)->last)
   7720 
   7721 /**
   7722  * first element
   7723  *
   7724  * \param
   7725  * a slab
   7726  */
   7727 #define slabFirst(a) (*((a)->array + (a)->head))
   7728 
   7729 /**
   7730  * index of first element
   7731  */
   7732 #define slabFirstIndex(a) ((a)->head)
   7733 
   7734 /**
   7735  * write the slab content to filename file
   7736  * No NULL checks are done on the parameters
   7737  *
   7738  * \param
   7739  *    filename file name string
   7740  */
   7741 #define slabWriteFilename(a, filename) do {\
   7742     FILE *UNIQVAR(f) = fopen(filename, "w");\
   7743     if (UNIQVAR(f)) {\
   7744       fwrite((a)->array + (a)->head, 1, sizeof(*((a)->array)) * slabCount(a), UNIQVAR(f));\
   7745       fclose(UNIQVAR(f));\
   7746     }\
   7747   } while(0)
   7748 
   7749 /**
   7750  * write the slab content to disk
   7751  * No NULL checks are done on the parameters
   7752  *
   7753  * \param
   7754  *    file already opened file
   7755  */
   7756 #define slabWrite(a, file) fwrite((a)->array + (a)->head, 1, sizeof(*((a)->array)) * slabCount(a), file)
   7757 
   7758 /**
   7759  * read a slab from filename file
   7760  * No NULL checks are done on the parameters
   7761  *
   7762  * \param
   7763  * filename file name string
   7764  */
   7765 #define slabReadFilename(a, filename) do {\
   7766     if (fileExists(filename)) {\
   7767       size_t UNIQVAR(sz) = fileSize(filename);\
   7768       FILE *UNIQVAR(f) = fopen(filename, "r");\
   7769       if (UNIQVAR(f)) {\
   7770         range(UNIQVAR(i), UNIQVAR(sz)/sizeof(*((a)->array))) {\
   7771           slabPush(a);\
   7772           fread(slabLastPtr(a), 1, sizeof(*((a)->array)), UNIQVAR(f));\
   7773         }\
   7774         fclose(UNIQVAR(f));\
   7775       }\
   7776     }\
   7777   } while(0)
   7778 
   7779 /**
   7780  * read a slab from disk
   7781  * No NULL checks are done on the parameters
   7782  *
   7783  * \param
   7784  *    file already opened file
   7785  */
   7786 #define slabRead(a, file) do {\
   7787     fseek(file, 0 , SEEK_END);\
   7788     size_t UNIQVAR(sz) = ftell(file);\
   7789     fseek(file, 0 , SEEK_SET);\
   7790     range(UNIQVAR(i), UNIQVAR(sz)/sizeof(*((a)->array))) {\
   7791       slabPush(a);\
   7792       fread(slabLastPtr(a), 1, sizeof(*((a)->array)), file);\
   7793     }\
   7794   } while(0)
   7795 
   7796 /**
   7797  * loop on slab elements
   7798  * element is a pointer to a value in the array
   7799  *
   7800  * slabForEach(&a, e) {
   7801  *    e->x = 0;
   7802  * }
   7803  */
   7804 #define slabForEach(name, element) \
   7805   ;size_t UNIQVAR(libsheepyInternalIndex) = (name)->head; \
   7806   for (slabElemPtrType(name) element = slabPtr(name, (name)->head) ; UNIQVAR(libsheepyInternalIndex) < (name)->last + 1 ; UNIQVAR(libsheepyInternalIndex)++, element = slabPtr(name, UNIQVAR(libsheepyInternalIndex)))
   7807 
   7808 /**
   7809  * enumerate slab elements
   7810  * index is the position of the element in the array
   7811  * index is declared as size_t and is available after the loop
   7812  * element is a pointer to a value in the array
   7813  *
   7814  * slabEnumerate(&a, i, e) {
   7815  *    e->x = 0;
   7816  *    printf("slabEnumerate %d\n", i);
   7817  * }
   7818  */
   7819 #define slabEnumerate(name, index, element) \
   7820   ; size_t index = (name)->head; \
   7821   for (slabElemPtrType(name) element = slabPtr(name, (name)->head) ; index < (name)->last + 1 ; index++, element = slabPtr(name, index))
   7822 
   7823 
   7824 /*
   7825  * end slab
   7826  */
   7827 
   7828 
   7829 /**
   7830  * static bitset
   7831  *
   7832  * no sanity checks are done
   7833  *
   7834  * Usage:
   7835  *
   7836  * staticBitsetT(typeName, u64 , 8);
   7837  *
   7838  * typeName bits;
   7839  *
   7840  * staticBitsetInit(&bits);
   7841  *
   7842  * staticBitset1(&bits, index);
   7843  *
   7844  * bool bit = staticBitsetGet(&bits, index);
   7845  *
   7846  */
   7847 
   7848 /**
   7849  * typedef for staticBitset
   7850  *
   7851  * \param
   7852  *   typeName typedef name
   7853  * \param
   7854  *   containerType element type in array: u8, u16, u32, u64...
   7855  * \param
   7856  *   count bit count in array
   7857  */
   7858 #define staticBitsetT(typeName, containerType, count)\
   7859   typedef struct {containerType map[BUCKETS(count, 8 * sizeof(containerType))];} typeName;
   7860 
   7861 #define staticBitsetInit staticBitsetClear
   7862 
   7863 /** bitset count */
   7864 #define staticBitsetCount(name) (sizeof((name)->map) * 8)
   7865 
   7866 /** clear all bits in bitset */
   7867 #define staticBitsetClear(name) memset(name, 0, sizeof(*(name)));
   7868 
   7869 /** bucket containing bit at given index */
   7870 #define staticBitsetBucket(name, index) (name)->map[index / (8 * sizeof((name)->map[0]))]
   7871 
   7872 /** set 0 at index */
   7873 #define staticBitset0(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] &= 0xFFFFFFFFFFFFFFFFUL ^ (1UL<<bitOffset);\
   7878   } while(0)
   7879 
   7880 /** set 1 at index*/
   7881 #define staticBitset1(name, index) 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     (name)->map[byteOffset] |= 1UL<<bitOffset;\
   7886   } while(0)
   7887 
   7888 /** set bit value at index*/
   7889 #define staticBitsetSet(name, index, value) do{\
   7890     var UNIQVAR(idx)         = index;\
   7891     size_t byteOffset        = UNIQVAR(idx) / (8 * sizeof((name)->map[0]));\
   7892     size_t bitOffset         = UNIQVAR(idx) % (8 * sizeof((name)->map[0]));\
   7893     /* 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));*/\
   7894     if (!value)\
   7895       (name)->map[byteOffset] &= 0xFFFFFFFFFFFFFFFFUL ^ (1UL<<bitOffset);\
   7896     else\
   7897       (name)->map[byteOffset] |= 1UL<<bitOffset;\
   7898   } while(0)
   7899 
   7900 /** invert bit at index */
   7901 #define staticBitsetInv(name, index) do{\
   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;\
   7906   } while(0)
   7907 
   7908 /** get bit at index */
   7909 #define staticBitsetGet(name, index) ({\
   7910     var UNIQVAR(idx)  = index;\
   7911     size_t byteOffset = UNIQVAR(idx) / (8 * sizeof((name)->map[0]));\
   7912     size_t bitOffset  = UNIQVAR(idx) % (8 * sizeof((name)->map[0]));\
   7913     ((name)->map[byteOffset] & (1UL<<bitOffset)) == 1UL<<bitOffset;\
   7914   })
   7915 
   7916 /**
   7917  * end static bitset
   7918  */
   7919 
   7920 /**
   7921  * bitset
   7922  * the underlying array is defined in the provided at macro or function
   7923  *
   7924  * no sanity checks are done
   7925  *
   7926  * a dynamic bitset can be created using slice and sliceAt
   7927  */
   7928 
   7929 #define bitsetModulo 8
   7930 
   7931 /** bucket containing bit at given index */
   7932 #define bitsetBucket(name, index) (name)->map[index / (bitsetModulo)]
   7933 
   7934 /** set 0 at index
   7935  * at must be macro or function taking 2 parameters:
   7936  * at(name, intIndex)
   7937  * and point to value at intIndex
   7938  */
   7939 #define bitset0(name, at, index) do{\
   7940     var UNIQVAR(idx)         = index;\
   7941     size_t byteOffset        = UNIQVAR(idx) / (bitsetModulo);\
   7942     size_t bitOffset         = UNIQVAR(idx) % (bitsetModulo);\
   7943     at(name, byteOffset)    &= 0xFFFFFFFFFFFFFFFFUL ^ (1UL<<bitOffset);\
   7944   } while(0)
   7945 
   7946 /** set 1 at index
   7947  * at must be macro or function taking 2 parameters:
   7948  * at(name, intIndex)
   7949  * and point to value at intIndex
   7950  */
   7951 #define bitset1(name, at, index) do{\
   7952     var UNIQVAR(idx)         = index;\
   7953     size_t byteOffset        = UNIQVAR(idx) / (bitsetModulo);\
   7954     size_t bitOffset         = UNIQVAR(idx) % (bitsetModulo);\
   7955     at(name, byteOffset)    |= 1UL<<bitOffset;\
   7956   } while(0)
   7957 
   7958 /** set bit value at index
   7959  * at must be macro or function taking 2 parameters:
   7960  * at(name, intIndex)
   7961  * and point to value at intIndex
   7962  */
   7963 #define bitsetSet(name, at, index, value) do{\
   7964     var UNIQVAR(idx)         = index;\
   7965     size_t byteOffset        = UNIQVAR(idx) / (bitsetModulo);\
   7966     size_t bitOffset         = UNIQVAR(idx) % (bitsetModulo);\
   7967     /* 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)); */\
   7968     if (!value)\
   7969       at(name, byteOffset) &= 0xFFFFFFFFFFFFFFFFUL ^ (1UL<<bitOffset);\
   7970     else\
   7971       at(name, byteOffset) |= 1UL<<bitOffset;\
   7972   } while(0)
   7973 
   7974 /** invert bit at index
   7975  * at must be macro or function taking 2 parameters:
   7976  * at(name, intIndex)
   7977  * and point to value at intIndex
   7978  */
   7979 #define bitsetInv(name, at, index) do{\
   7980     var UNIQVAR(idx)         = index;\
   7981     size_t byteOffset        = UNIQVAR(idx) / (bitsetModulo);\
   7982     size_t bitOffset         = UNIQVAR(idx) % (bitsetModulo);\
   7983     at(name, byteOffset)    ^= 1UL<<bitOffset;\
   7984   } while(0)
   7985 
   7986 /**
   7987  * get bit at index
   7988  * at must be macro or function taking 2 parameters:
   7989  * at(name, intIndex)
   7990  * and return the value at intIndex
   7991  */
   7992 #define bitsetGet(name, at, index) ({\
   7993     var UNIQVAR(idx)  = index;\
   7994     size_t byteOffset = UNIQVAR(idx) / (bitsetModulo);\
   7995     size_t bitOffset  = UNIQVAR(idx) % (bitsetModulo);\
   7996     (at(name, byteOffset) & (1UL<<bitOffset)) == 1UL<<bitOffset;\
   7997   })
   7998 
   7999 /**
   8000  * end bitset
   8001  */
   8002 
   8003 /**
   8004  * bitfield array
   8005  *
   8006  * a field is a group of bit representing an int stored in a larger int
   8007  *
   8008  * bitfield array is an array of fields (short int) similar to bitset
   8009  *
   8010  * Example:
   8011  *
   8012  * u64 v = 0;             // field storage
   8013  * FIELD_SET(v, 3, 1, 0); // field is 2 bits from bit 0 to bit 1, set value 3
   8014  *
   8015  * u8 field = FIELD_GET(v, 1, 0); // get value in field at bit 0 to 1
   8016  *
   8017  * // declare a bitfield array
   8018  * // the array has 256 elements and each element is a 2 bit integer
   8019  * BITFIELD_VAR(bitfields, 256, 2) = init0Var;
   8020  *
   8021  * // set value for element at index 255
   8022  * BITFIELD_SET(bitfields, 255, 3, 2);
   8023  * // get value for element at index 255
   8024  * v = BITFIELD_GET(bitfields, 255, 2);
   8025  *
   8026  */
   8027 
   8028 /**
   8029  * set bitfield value in destination (opposite of EXTRACT macro)
   8030  *
   8031  * only bits between msb and lsb are set in dst
   8032  *
   8033  * \param
   8034  *   dst destination, unsigned integer (u8, u16, u32, u64)
   8035  * \param
   8036  *   val value to set, the value is shifted to lsb
   8037  * \param
   8038  *   msb most significant bit in dst to be set
   8039  * \param
   8040  *   lsb least significant bit in dst to be set
   8041  */
   8042 #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))
   8043 
   8044 #define FIELD_GET EXTRACT
   8045 
   8046 /**
   8047  * set bitfield value in destination, given bitfield index and length
   8048  *
   8049  * (index+1)*len-1 must be lower or equal to 8*sizeof(dst),
   8050  * otherwise val will be truncated
   8051  *
   8052  * \param
   8053  *   dst destination, unsigned integer (u8, u16, u32, u64)
   8054  * \param
   8055  *   index index of the bitfield in dst (bit index*len is lsb)
   8056  * \param
   8057  *   val value to set, the value is shifted to lsb
   8058  * \param
   8059  *   len bitfield length in dst
   8060  */
   8061 #define FIELD_SETL(dst, index, val, len) FIELD_SET(dst, val, ((index)+1)*(len)-1, (index)*(len))
   8062 
   8063 /**
   8064  * set bitfield value in array of bitfields
   8065  * the boundaries are not checked
   8066  *
   8067  * \param
   8068  *   array array of u64
   8069  * \param
   8070  *   index index of the bitfield in array (bit index*len is lsb)
   8071  * \param
   8072  *   val value to set, the value is shifted to the correct position
   8073  * \param
   8074  *   len bitfield length in array, must divide 64 (2, 4, 8, 16, 32)
   8075  */
   8076 #define BITFIELD_SET(array, index, val, len) FIELD_SET((array)[((index)*(len))/64], val, ((index)*(len))%64+(len)-1, ((index)*(len))%64)
   8077 
   8078 /**
   8079  * get bitfield value in array of bitfields
   8080  * the boundaries are not checked
   8081  *
   8082  * \param
   8083  *   array array of u64
   8084  * \param
   8085  *   index index of the bitfield in array (bit index*len is lsb)
   8086  * \param
   8087  *   len bitfield length in array, must divide 64 (2, 4, 8, 16, 32)
   8088  */
   8089 #define BITFIELD_GET(array, index, len) EXTRACT((array)[((index)*(len))/64], ((index)*(len))%64+(len)-1, ((index)*(len))%64)
   8090 
   8091 /**
   8092  * return number of u64 necessary to hold count bitfields of length len
   8093  */
   8094 #define BITFIELD_SIZE(count, len, containerType) BUCKETS((count)*(len), 8 * sizeof(containerType))
   8095 
   8096 /**
   8097  * declare an array to hold count bitfields of length len
   8098  */
   8099 #define BITFIELD_VAR(array, count, len) u64 array[BITFIELD_SIZE(count, len, u64)]
   8100 
   8101 /**
   8102  * end bitfield
   8103  */
   8104 
   8105 // get monotonic time in ns
   8106 uint64_t getMonotonicTime(void) MUST_CHECK;
   8107 
   8108 // sleep nanoseconds
   8109 int nanoSleepF(uint64_t time) MUST_CHECK;
   8110 #define nanoSleep(time) pError0(nanoSleepF(time))
   8111 
   8112 /** sleep nanoseconds */
   8113 #define nanoSleep(time) pError0(nanoSleepF(time))
   8114 
   8115 /** nanoSleep and error code */
   8116 #define nanoSleepE(time, cmd) pErrorCmd(nanoSleepF(time), == 0, cmd)
   8117 
   8118 /** sleep microseconds */
   8119 #define usSleep(time) pError0(nanoSleepF(1000 * (uint64_t)time))
   8120 
   8121 /** sleep miliseconds */
   8122 #define msSleep(time) pError0(nanoSleepF(1000000 * (uint64_t)time))
   8123 
   8124 
   8125 #ifdef __GNUC__
   8126 #define UNUSED __attribute__ ((unused))
   8127 #define DEPRECATED __attribute__ ((deprecated))
   8128 #define PACKED __attribute__((__packed__))
   8129 
   8130 /**
   8131  * cleanup calls a function when the variable is out of scope
   8132  *
   8133  * Also checkout the clean* macros using the cleanup attribute (cleanCharP, ...)
   8134  *
   8135  * Example:
   8136  * void cleanUp(int *val) {
   8137  *   logVarG(*val);
   8138  * }
   8139  * int a CLEANUP(cleanUp) = 1;
   8140  * a++;
   8141  *
   8142  * The cleanUp function is called when the variable a is out of scope
   8143  *
   8144  */
   8145 #define CLEANUP(func) __attribute__((cleanup(func)))
   8146 
   8147 /**
   8148  * suppress warning: this statement may fall through [-Wimplicit-fallthrough=]
   8149  *
   8150  *    switch (cond)
   8151  *    {
   8152  *    case 1:
   8153  *      bar (0);
   8154  *      FALLTHRU;
   8155  *    default:
   8156  *    }
   8157  */
   8158 #if __GNUC__ >= 7
   8159 #define FALLTHRU __attribute__ ((fallthrough))
   8160 #else
   8161 #define FALLTHRU
   8162 #endif
   8163 
   8164 /** always inline function */
   8165 #define AINLINE         inline __attribute__ ((always_inline))
   8166 
   8167 /** never inline function */
   8168 #define NOINLINE      __attribute__ ((noinline))
   8169 
   8170 /**
   8171  * pure function (no effect on assembly code with gcc 10)
   8172  * a pure function is one that has no side effects and whose return value reflects only
   8173  * the function's parameters or nonvolatile global variables.
   8174  * Any parameter or global variable access must be read-only
   8175  */
   8176 //#define PURE          __attribute__ ((pure))
   8177 
   8178 /**
   8179  * const function (no effect on assembly code with gcc 10)
   8180  * a const function is a pure function that cannot access global variables
   8181  * and cannot take pointers as parameters.
   8182  */
   8183 //#define CONST         __attribute__ ((const))
   8184 
   8185 /** function that always terminate the program, the compile optimizes the caller code better */
   8186 #define NORETURN      __attribute__ ((noreturn))
   8187 
   8188 /** function returning a pointer to a newly allocated buffer */
   8189 #define AMALLOC       __attribute__ ((malloc))
   8190 
   8191 /** mark a function as used */
   8192 #define USED          __attribute__ ((used))
   8193 
   8194 /** force alignment */
   8195 #define ALIGN(X)      __attribute__ ((aligned, (x)))
   8196 #define ALIGN_MAX     __attribute__ ((aligned))
   8197 
   8198 /** branch anotation (use profile feedback-directed optimization instead) */
   8199 //#define likely(x)       __builtin_expect (!!(x), 1)
   8200 //#define unlikely(x)     __builtin_expect (!!(x), 0)
   8201 
   8202 #else
   8203 #define UNUSED
   8204 #define DEPRECATED
   8205 #define PACKED
   8206 #define CLEANUP
   8207 #define FALLTHRU
   8208 #define AINLINE
   8209 #define NOINLINE
   8210 #define PURE
   8211 #define CONST
   8212 #define NORETURN
   8213 #define AMALLOC
   8214 #define MUST_CHECK
   8215 #define USED
   8216 #define ALIGN(X)
   8217 #define ALIGN_MAX
   8218 #define likely(x)    (x)
   8219 #define unlikely(x)  (x)
   8220 #endif
   8221 
   8222 #endif // _libsheepyH
   8223 // vim: set expandtab ts=2 sw=2: