Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* VOID.H - Universal Header File.
- void.h ver1.45 for Digital Mars C by FrozenVoid original content licensed under UFIL1.02 http://pastebin.com/L3p9XK3T
- portions of file are licensed under other licenses(check source of content)
- @..\dmc -gg -Nc -Jm -o+all -o-dv %1.c -o%1.exe
- */
- /* Features:
- #include default C libraries.
- short syntax for type declarations [type][bytes]([p=restrict pointer]*Level)
- short syntax for main/exitmain
- short syntax for common keywords
- u8 rdtsc() return 64bit CPU cycle counter.
- u[num] ru[num]() returns num random bytes
- u8 rrange(u8 max) return random u8 number in range 0<>max
- u1* chrgen(resstr,size) return a random string of [size] bytes composed from random characters in resstr.
- sas(expr,errmsg) static(compile time) assert wil fail if expr isn't true with errmsg
- u1* getfile(u1* filename,u8* size) copy file co
- ntent to pointer and set size to filesize.
- u8 putfile(u1* ptr,u8 size,u1* filename) copy content to filename, return number of bytes written
- u4* hash(u1* text,u8 len) return 16byte MurmurHash3 of string, len is length of string/text;
- f10 ent(u1* str,u8 size) return entropy of string(size of string)
- v0 prbin(s4 num) print binary value of int32
- various bithacks,murmurhash,etc
- */
- #ifndef __DMC__
- #error "This header contains Digital Mars C-only code."
- #endif
- #pragma once
- //void.h default includes
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
- #include <errno.h>
- #include <ctype.h>
- #include <fenv.h>
- #include <float.h>
- #include <inttypes.h>
- #include <limits.h>
- #include <math.h>
- #include <setjmp.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stddef.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <time.h>
- #include <string.h>
- #define d #define
- // Typedefs
- d td typedef
- td uint8_t u1;
- td uint16_t u2;
- td uint32_t u4;
- td uint64_t u8;
- td int8_t s1;
- td int16_t s2;
- td int32_t s4;
- td int64_t s8;
- td float f4;
- td double f8;
- td long double f10;
- td void v0;
- //Pointers restrict+unsigned 3levels
- td restrict u1* u1p;
- td restrict u1** u1pp;
- td restrict u1*** u1ppp;
- td restrict u2* u2p;
- td restrict u2** u2pp;
- td restrict u2*** u2ppp;
- td restrict u4* u4p;
- td restrict u4** u4pp;
- td restrict u4*** u4ppp;
- td restrict u8* u8p;
- td restrict u8** u8pp;
- td restrict u8*** u8ppp;
- td restrict v0* v0p;
- td restrict v0** v0pp;
- td restrict v0*** v0ppp;
- //aliases
- d STDSTART s4 main(s4 argc,u1**argv){;
- d STDEND ;return 0;};
- d FASTSTART v0 main(v0){;
- d FASTEND ;};
- d pr printf
- d ma malloc
- d go goto
- d wh while
- d br break;
- d sw switch
- d el else
- d st struct
- d ts typedef struct
- d re return
- d sta static
- d reg register
- d con continue
- d iv inline void
- d ln(x) (_msize(x))//object size in malloced bytes
- // constants
- //Common functions
- //BITHACKS
- //set,clear,toggle,check bit of integer
- //http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/
- d setb(o,p) o|=(1<<p) //byte| 1<< pos
- d clrb(o,p) o&=(~(1<<p)) // byte | 11101111
- d togb(o,p) o^=(1<<p)
- d chkb(o,p) ((o>>p)&1)
- //Turnoff rightmost bit
- d offlast1(x) (x&(x-1))
- d onlast0(x) (x|(x+1))
- d last1(x) (x&(-x))
- d last0(x) ((~x)&(x+1))
- //sign of integer
- d signof(x) (x>>((sizeof(x)*8)-1)) //-1/0
- d even(x) (!(x&1))
- d odd(x) (x&1)
- //http://graphics.stanford.edu/~seander/bithacks.html
- //absolute values
- d abs(x) ((x^(x>>(sizeof(x)*8-1)))-(x>>(sizeof(x)*8-1)))
- //minimum and maximum
- d min(x,y) (y ^ ((x ^ y) & -(x < y)))
- d max(x,y) (x ^ ((x ^ y) & -(x < y)))
- //is power of 2
- d is2pow(x) (x&&(!(x & (x - 1))))
- //Conditionally set or clear bits without branching
- d scbits(x,bitmask,cond) (x&(~bitmask))|((-cond)&bitmask)
- //Conditional negation(if flag is true/1)
- d condneg(x,flag) ((x^(-flag))+flag)
- //merge bits from x,y from bitmask:1=ybit,0=xbit
- d mergebits(x,y,bitmask) (x^((x^y)&mask))
- // coutn bit in int32
- inline s4 counts4bits(s4 num){
- s4 v=num-((num>>1)&0x55555555);
- v=(v & 0x33333333) + ((v >> 2) & 0x33333333);
- re (((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24);}
- inline s8 counts8bits(s8 num){//untested
- s4 v=num-((num>>1)&0x5555555555555555ULL);
- v=(v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
- re (((v + (v >> 4) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL) >> 56);}
- s4 inline s4parity(s4 num){
- s4 v=num;
- v^=(v>>16);
- v^=(v>>8);
- v^=(v>>4);
- v&=0xf;
- re ((0x6996 >> v) & 1);
- }
- s1 inline s1parity(s1 num){
- s4 v=num;
- v^=(v>>4);
- v&=0xf;
- re ((0x6996 >> v) & 1);
- }
- //Random integers 1*,2*,4,8 bytes
- //http://en.wikipedia.org/wiki/Xorshift
- d DSEC 1 //0 low entropy/faster 1=highentropy
- inline u8 rdtsc(){__asm{RDTSC}} //timestamp
- uint32_t ru4(v0) {//xor128 RNG
- static uint32_t x = 123456789;
- static uint32_t y = 362436069;
- static uint32_t z = 521288629;
- static uint32_t w = 88675123;
- uint32_t t;
- t = x ^ (x << 11);
- x = y; y = z; z = w;
- w = w ^ (w >> 19) ^ (t ^ (t >> 8));
- return w;
- }
- u8 ru8(v0){
- u8 res;u4* h=(u4*)&res;
- h[0]=ru4();
- h[1]=ru4();
- re res;
- }
- u1 ru1(v0){
- //select 1/4 of int32
- u4 r=ru4();
- u4 sh=(r&3)<<3;
- #ifdef DSEC
- re (u1)((ru4()&(0xFF<<(sh)))>>(sh));
- #else
- re (u1)((r&(0xFF<<(sh)))>>(sh));
- #endif
- }
- u2 ru2(v0){
- u4 r=ru4();u4 sh=(r&1)<<4;
- #ifdef DSEC
- re (u2)((ru4()&(0xFFFF<<(sh)))>>(sh));
- #else
- re (u2)((r&(0xFFFF<<(sh)))>>(sh));
- #endif
- }
- /*
- random text: 0-x positon in string.
- */
- u8 rrange(u8 max){
- f10 div=((f10)ULLONG_MAX);
- u8 r=ru8();if(!r)r++;
- f10 d2=(((f10)r)/div)*((f10)max);//0..1 rnd number
- u8 res=(u8)d2;
- re res;
- }
- u1* chrgen(u1* str,u8 ressize){
- u8 strl=strlen(str);//"12" string index max
- u1* res=ma(ressize);u8 i=0;
- for(i=0;i<ressize;i++){res[i]=str[rrange(strl)];}
- re res;
- }
- v0 prbin(s4 num){//prints binary value of int32
- s4 i;
- for(i=31;i>-1;i--){putchar(chkb(num,i)+48);}
- }
- const u1 alphanumeric[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- u4 inline countwords(u1* str,u4 strsize){
- u4 reg count=0;u4 reg old=0;u4 reg state=0;
- u4 i;
- for(i=0;i<strsize;i++){
- state=alphanumeric[str[i]];
- count+=(old^state);old=state;}
- count>>=1;
- re count;}
- u4 inline countlines(u1* str,u4 strsize){
- u4 reg count=1;u4 i=strsize;
- wh(i--){count+=(!(str[i]^'\n'));};
- re count;
- }
- //----------------------------------------------
- //Debug error in0,out1,err2
- // ASCII !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
- #define epr(...) fprintf(stderr, __VA_ARGS__)
- //static assert
- #define sas(expr,errmsg) \
- int __static_assert(int errmsg##static_assert_failed[(expr)?1:-1])
- d getext(filename) strrchr(filename,'.')
- d hasdigits(str) strpbrk(str,"0123456789")
- d startswithdigits(str) (strcspn(str,"0123456789")==0)
- //Transfer file content into a pointer.
- u1* getfile(u1* filename,u8* size){
- FILE* in=fopen(filename,"rb");
- if(in==NULL){size[0]=0;perror("File access failed");return NULL;};
- fseek(in,0,SEEK_END);
- *size=(u8)ftell(in);rewind(in);
- u1* resfile=ma(size[0]);
- fread(resfile,size[0],1,in);
- fclose(in);
- re resfile;
- }
- //transfer pointer content into a file
- u8 putfile(u1* ptr,u8 size,u1* filename){
- FILE* out=fopen(filename,"wb");
- if(!out){perror("Cannot write to file");return 0;}
- u8 res=fwrite(ptr,size,1,out);fclose(out);
- re res;}
- // Entropy calculation
- f10 ent(u1* str,u8 size){
- f10 entropy=0;f10 prob;f10 ml2=logl(2);
- u8 counts[256]={0};
- u8 iter=0;
- wh(iter<size){counts[str[iter++]]++;};iter=0;
- for(iter=0;iter<256;iter++){
- if(!counts[iter]){;con;}
- prob=1.0*((f10)counts[iter]/(f10)size);
- entropy-=prob*(logl(prob)/ml2);;}
- re entropy;
- }
- #undef d
- //-------------MurmurHash3
- //http://en.wikipedia.org/wiki/MurmurHash
- // Platform-specific functions and macros
- #ifdef __GNUC__
- #define FORCE_INLINE __attribute__((always_inline)) inline
- #else
- #define FORCE_INLINE
- #endif
- static inline FORCE_INLINE uint32_t rotl32 ( uint32_t x, int8_t r )
- {
- return (x << r) | (x >> (32 - r));
- }
- static inline FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r )
- {
- return (x << r) | (x >> (64 - r));
- }
- #define ROTL32(x,y) rotl32(x,y)
- #define ROTL64(x,y) rotl64(x,y)
- #define BIG_CONSTANT(x) (x##LLU)
- //-----------------------------------------------------------------------------
- // Block read - if your platform needs to do endian-swapping or can only
- // handle aligned reads, do the conversion here
- #define getblock(p, i) (p[i])
- //-----------------------------------------------------------------------------
- // Finalization mix - force all bits of a hash block to avalanche
- static inline FORCE_INLINE uint32_t fmix32 ( uint32_t h )
- {
- h ^= h >> 16;
- h *= 0x85ebca6b;
- h ^= h >> 13;
- h *= 0xc2b2ae35;
- h ^= h >> 16;
- return h;
- }
- //----------
- static inline FORCE_INLINE uint64_t fmix64 ( uint64_t k )
- {
- k ^= k >> 33;
- k *= BIG_CONSTANT(0xff51afd7ed558ccd);
- k ^= k >> 33;
- k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
- k ^= k >> 33;
- return k;
- }
- //-----------------------------------------------------------------------------
- void MurmurHash3_x86_32 ( const void * key, int len,
- uint32_t seed, void * out )
- {
- const uint8_t * data = (const uint8_t*)key;
- const int nblocks = len / 4;
- int i;
- uint32_t h1 = seed;
- uint32_t c1 = 0xcc9e2d51;
- uint32_t c2 = 0x1b873593;
- //----------
- // body
- const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
- for(i = -nblocks; i; i++)
- {
- uint32_t k1 = getblock(blocks,i);
- k1 *= c1;
- k1 = ROTL32(k1,15);
- k1 *= c2;
- h1 ^= k1;
- h1 = ROTL32(h1,13);
- h1 = h1*5+0xe6546b64;
- }
- //----------
- // tail
- const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
- uint32_t k1 = 0;
- switch(len & 3)
- {
- case 3: k1 ^= tail[2] << 16;
- case 2: k1 ^= tail[1] << 8;
- case 1: k1 ^= tail[0];
- k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
- };
- //----------
- // finalization
- h1 ^= len;
- h1 = fmix32(h1);
- *(uint32_t*)out = h1;
- }
- //-----------------------------------------------------------------------------
- void MurmurHash3_x86_128 ( const void * key, const int len,
- uint32_t seed, void * out )
- {
- const uint8_t * data = (const uint8_t*)key;
- const int nblocks = len / 16;
- int i;
- uint32_t h1 = seed;
- uint32_t h2 = seed;
- uint32_t h3 = seed;
- uint32_t h4 = seed;
- uint32_t c1 = 0x239b961b;
- uint32_t c2 = 0xab0e9789;
- uint32_t c3 = 0x38b34ae5;
- uint32_t c4 = 0xa1e38b93;
- //----------
- // body
- const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
- for(i = -nblocks; i; i++)
- {
- uint32_t k1 = getblock(blocks,i*4+0);
- uint32_t k2 = getblock(blocks,i*4+1);
- uint32_t k3 = getblock(blocks,i*4+2);
- uint32_t k4 = getblock(blocks,i*4+3);
- k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
- h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
- k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
- h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
- k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
- h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
- k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
- h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
- }
- //----------
- // tail
- const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
- uint32_t k1 = 0;
- uint32_t k2 = 0;
- uint32_t k3 = 0;
- uint32_t k4 = 0;
- switch(len & 15)
- {
- case 15: k4 ^= tail[14] << 16;
- case 14: k4 ^= tail[13] << 8;
- case 13: k4 ^= tail[12] << 0;
- k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
- case 12: k3 ^= tail[11] << 24;
- case 11: k3 ^= tail[10] << 16;
- case 10: k3 ^= tail[ 9] << 8;
- case 9: k3 ^= tail[ 8] << 0;
- k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
- case 8: k2 ^= tail[ 7] << 24;
- case 7: k2 ^= tail[ 6] << 16;
- case 6: k2 ^= tail[ 5] << 8;
- case 5: k2 ^= tail[ 4] << 0;
- k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
- case 4: k1 ^= tail[ 3] << 24;
- case 3: k1 ^= tail[ 2] << 16;
- case 2: k1 ^= tail[ 1] << 8;
- case 1: k1 ^= tail[ 0] << 0;
- k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
- };
- //----------
- // finalization
- h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
- h1 += h2; h1 += h3; h1 += h4;
- h2 += h1; h3 += h1; h4 += h1;
- h1 = fmix32(h1);
- h2 = fmix32(h2);
- h3 = fmix32(h3);
- h4 = fmix32(h4);
- h1 += h2; h1 += h3; h1 += h4;
- h2 += h1; h3 += h1; h4 += h1;
- ((uint32_t*)out)[0] = h1;
- ((uint32_t*)out)[1] = h2;
- ((uint32_t*)out)[2] = h3;
- ((uint32_t*)out)[3] = h4;
- }
- //-----------------------------------------------------------------------------
- void MurmurHash3_x64_128 ( const void * key, const int len,
- const uint32_t seed, void * out )
- {
- const uint8_t * data = (const uint8_t*)key;
- const int nblocks = len / 16;
- int i;
- uint64_t h1 = seed;
- uint64_t h2 = seed;
- uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
- uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
- //----------
- // body
- const uint64_t * blocks = (const uint64_t *)(data);
- for(i = 0; i < nblocks; i++)
- {
- uint64_t k1 = getblock(blocks,i*2+0);
- uint64_t k2 = getblock(blocks,i*2+1);
- k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
- h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
- k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
- h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
- }
- //----------
- // tail
- const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
- uint64_t k1 = 0;
- uint64_t k2 = 0;
- switch(len & 15)
- {
- case 15: k2 ^= (uint64_t)(tail[14]) << 48;
- case 14: k2 ^= (uint64_t)(tail[13]) << 40;
- case 13: k2 ^= (uint64_t)(tail[12]) << 32;
- case 12: k2 ^= (uint64_t)(tail[11]) << 24;
- case 11: k2 ^= (uint64_t)(tail[10]) << 16;
- case 10: k2 ^= (uint64_t)(tail[ 9]) << 8;
- case 9: k2 ^= (uint64_t)(tail[ 8]) << 0;
- k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
- case 8: k1 ^= (uint64_t)(tail[ 7]) << 56;
- case 7: k1 ^= (uint64_t)(tail[ 6]) << 48;
- case 6: k1 ^= (uint64_t)(tail[ 5]) << 40;
- case 5: k1 ^= (uint64_t)(tail[ 4]) << 32;
- case 4: k1 ^= (uint64_t)(tail[ 3]) << 24;
- case 3: k1 ^= (uint64_t)(tail[ 2]) << 16;
- case 2: k1 ^= (uint64_t)(tail[ 1]) << 8;
- case 1: k1 ^= (uint64_t)(tail[ 0]) << 0;
- k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
- };
- //----------
- // finalization
- h1 ^= len; h2 ^= len;
- h1 += h2;
- h2 += h1;
- h1 = fmix64(h1);
- h2 = fmix64(h2);
- h1 += h2;
- h2 += h1;
- ((uint64_t*)out)[0] = h1;
- ((uint64_t*)out)[1] = h2;
- }
- //===============
- u4* hash(u1* text,u8 len){
- u4* res=ma(16);
- MurmurHash3_x86_128(text,len,0x12345678,res);
- re res;
- }
Advertisement
Add Comment
Please, Sign In to add comment