code:
#ifndef JSPARSER_H
#define JSPARSER_H

#include <string>
#include <vector>
#include <map>
// for gcc & shared_ptr
#include <iostream>
#include <memory>

// Internal JS types: String, Number, Function, Array, Object
// blocks/scopes?
class js_internal_storage {
public:
    // toBool
    // toString
    // toNumber
    // toFunction
    // toArray
    // toObject
    // toReference
    // toForward
    virtual ~js_internal_storage() = default;
};

// deprecated
/*
class js_scope {
public:
    js_scope *parent;
    // what do we need children for?
    // a callstack only includes it's parents (in JS?)
    std::vector<js_scope> children;
    js_scope() {
        parent = nullptr;
    }
    std::map<std::string, std::string> variables;
    std::map<std::string, js_internal_storage *> data;
    // maybe a vector of resolve on execution assignments...
    // feel like we need an instruction pointer...
    // esp. for loops
    // but how we address tokens, by index?
    // could just be strings tbh
    //std::vector<std::string> forwardExpressions;
    std::vector<std::string> forwardCalls;
};
*/

// maybe singletons?
class js_bool : public js_internal_storage {
public:
    bool value;
};

class js_string : public js_internal_storage {
public:
    std::string value;
};

class js_number : public js_internal_storage {
public:
    signed long value;
};

class js_object : public js_internal_storage {
public:
    std::map<std::string, js_internal_storage *> value;
};

class js_array : public js_internal_storage {
public:
    std::vector<js_internal_storage> value;
};

// we probably should extend js_object
class js_function : public js_internal_storage {
public:
    std::vector<std::string> tokens;
    std::vector<std::string> parameters; // incoming call or defined vars?
    js_function *parentScope = nullptr;
    js_object locals;
    //js_scope scope;
};

class js_reference : public js_internal_storage {
public:
    js_internal_storage *ptr; // to a function
};

class js_forward : public js_internal_storage {
public:
    std::string expression;
};

std::string typeOfStorage(js_internal_storage *storage);
// should this be a member function?
js_internal_storage *jsLocateKey(const js_function *scope, const std::string key);

// left side deference
js_internal_storage **getObjectKeyPointer(const std::string input, const js_function *scope);
// right side deference
js_internal_storage *dereferenceObject(const std::string input, const js_function *scope);
bool dereferenceHasBase(const std::string input, const js_function *scope);
js_function *makeFunctionFromString(const std::string body, const std::string prototype, js_function *parent);
// FIXME: should be a member function
void jsDisplayScope(const js_function *scope, size_t level);
size_t findClosing(std::string token, size_t start, char open, char close);
size_t locateFunctionNameEnd(std::string source, size_t start);
size_t locateFunctionParamsEnd(std::string source, size_t start);

// locate the end of single quoted expression
// start after ', return at '
size_t locateSingleQuoteEnd(const std::string source, const size_t start);

// locate the end of double quoted expression
// start after ", return at "
size_t locateDoubleQuoteEnd(const std::string source, const size_t start);
size_t locateRegexEnd(const std::string source, const size_t start);
size_t getNextExpression(const std::string source, const size_t start);
size_t parseFunctionBody(std::string source, size_t start);

//js_internal_storage *doFunctionCall(js_function *func, std::string params, js_function &scope);
js_internal_storage *jsFunctionCall(std::string funcName, js_function *func, std::string params, js_function &scope);
js_internal_storage *doExpression(js_function &rootScope, std::string token);
bool doAssignment(js_function &rootScope, std::string token);

void parseArray(js_function &rootScope, std::string token);
js_array *jsGetArray(js_function &rootScope, std::string token);
//js_internal_storage *parseExpression(js_function &rootScope, std::string token);
void parseJSON(js_function &rootScope, std::string token);
js_object *jsGetObject(js_function &rootScope, std::string token);

std::vector<std::string> jsGetTokens(const std::string &source, const size_t start);
// belongs in js_function
js_internal_storage *jsParseTokens(const std::vector<std::string> &tokens, js_function *scope);

class JavaScript {
public:
    JavaScript() {
        this->setUpRoot();
    }
    void setUpRoot() {
        // set up default window reference
        js_reference *window = new js_reference;
        window->ptr = &rootScope;
        rootScope.locals.value["window"] = window;
    }
    void clear() {
        tokens.clear();
        /*
        rootScope.parent = nullptr;
        rootScope.children.clear();
        rootScope.variables.clear();
        */
        delete rootScope.locals.value["window"];
        this->setUpRoot();
        rootScope.locals.value.clear();
    }
    // has to be called after the scopes are applied
    // actually maybe not with the forward system and parse/exec split
    void parse(const std::string);
    void append(const std::shared_ptr<JavaScript> &source);
    void applyScope(const std::shared_ptr<JavaScript> &source);
    void execute();
    // each token is one statement
    std::vector<std::string> tokens;
    // we're just settings the rootScope.variables
    std::vector<std::string> definitions; // all var declarations and their expressions
    std::vector<std::string> instructions; // then a list of all remaining expressions and function calls
    js_function rootScope;
    //js_scope rootScope;
};

#endif

repo_name: despair/netrunner

license: mit


code:
//-----------------------------------------------------------------------------
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.

// Note - The x86 and x64 versions do _not_ produce the same results, as the
// algorithms are optimized for their respective platforms. You can still
// compile and run any of them on any platform, but your performance with the
// non-native version will be less than optimal.

#include "Murmur3.h"

//-----------------------------------------------------------------------------
// Platform-specific functions and macros

#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#define GCC_VERSION (__GNUC__ * 10000 \
    + __GNUC_MINOR__ * 100 \
    + __GNUC_PATCHLEVEL__)

/* Test for GCC > 6.0.0, which supports push/pop similar to MS C/C++ */
#if GCC_VERSION > 60000
#pragma GCC diagnostic push
#endif

// Microsoft Visual Studio

#if defined(_MSC_VER)

#define FORCE_INLINE	__forceinline

#include <stdlib.h>

#define ROTL32(x,y)	_rotl(x,y)
#define ROTL64(x,y)	_rotl64(x,y)

#define BIG_CONSTANT(x) (x)

// Other compilers

#else	// defined(_MSC_VER)

#define	FORCE_INLINE inline __attribute__((always_inline))

inline uint32_t rotl32 ( uint32_t x, int8_t r )
{
  return (x << r) | (x >> (32 - r));
}

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)

#endif // !defined(_MSC_VER)

//-----------------------------------------------------------------------------
// Block read - if your platform needs to do endian-swapping or can only
// handle aligned reads, do the conversion here

FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i )
{
  return p[i];
}

FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i )
{
  return p[i];
}

//-----------------------------------------------------------------------------
// Finalization mix - force all bits of a hash block to avalanche

FORCE_INLINE uint32_t fmix32 ( uint32_t h )
{
  h ^= h >> 16;
  h *= 0x85ebca6b;
  h ^= h >> 13;
  h *= 0xc2b2ae35;
  h ^= h >> 16;

  return h;
}

//----------

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 = static_cast<const uint8_t*>(key);
  const int nblocks = len / 4;

  uint32_t h1 = seed;

  const uint32_t c1 = 0xcc9e2d51;
  const uint32_t c2 = 0x1b873593;

  //----------
  // body

  const uint32_t * blocks = reinterpret_cast<const unsigned int *>(data + nblocks*4);

  for(int i = -nblocks; i; i++)
  {
    uint32_t k1 = getblock32(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 = (data + nblocks*4);

  uint32_t k1 = 0;

  switch(len & 3) {
    case 3: k1 ^= static_cast<unsigned int>(tail[2]) << 16; // fall-through
    case 2: k1 ^= static_cast<unsigned int>(tail[1]) << 8; // fall-through
    case 1: k1 ^= static_cast<unsigned int>(tail[0]);
            k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
    break;
    default:
    break;
  };

  //----------
  // finalization

  h1 ^= static_cast<unsigned int>(len);

  h1 = fmix32(h1);

  *static_cast<uint32_t*>(out) = h1;
}

//-----------------------------------------------------------------------------

void MurmurHash3_x86_128 ( const void * key, const int len,
                           uint32_t seed, void * out )
{
  const uint8_t * data = static_cast<const uint8_t*>(key);
  const int nblocks = len / 16;

  uint32_t h1 = seed;
  uint32_t h2 = seed;
  uint32_t h3 = seed;
  uint32_t h4 = seed;

  const uint32_t c1 = 0x239b961b;
  const uint32_t c2 = 0xab0e9789;
  const uint32_t c3 = 0x38b34ae5;
  const uint32_t c4 = 0xa1e38b93;

  //----------
  // body

  const uint32_t * blocks = reinterpret_cast<const uint32_t *>(data + nblocks*16);

  for(int i = -nblocks; i; i++)
  {
    uint32_t k1 = getblock32(blocks,i*4+0);
    uint32_t k2 = getblock32(blocks,i*4+1);
    uint32_t k3 = getblock32(blocks,i*4+2);
    uint32_t k4 = getblock32(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 = (data + nblocks*16);

  uint32_t k1 = 0;
  uint32_t k2 = 0;
  uint32_t k3 = 0;
  uint32_t k4 = 0;

  // These are supposed to fall through
  switch(len & 15) {
  case 15: k4 ^= static_cast<unsigned int>(tail[14]) << 16; // fall-through
  case 14: k4 ^= static_cast<unsigned int>(tail[13]) << 8; // fall-through
  case 13: k4 ^= static_cast<unsigned int>(tail[12]) << 0;
           k4 *= c4; k4  = ROTL32(k4,18); k4 *= c1; h4 ^= k4;

  case 12: k3 ^= static_cast<unsigned int>(tail[11]) << 24; // fall-through
  case 11: k3 ^= static_cast<unsigned int>(tail[10]) << 16; // fall-through
  case 10: k3 ^= static_cast<unsigned int>(tail[ 9]) << 8; // fall-through
  case  9: k3 ^= static_cast<unsigned int>(tail[ 8]) << 0;
           k3 *= c3; k3  = ROTL32(k3,17); k3 *= c4; h3 ^= k3;

  case  8: k2 ^= static_cast<unsigned int>(tail[ 7]) << 24; // fall-through
  case  7: k2 ^= static_cast<unsigned int>(tail[ 6]) << 16; // fall-through
  case  6: k2 ^= static_cast<unsigned int>(tail[ 5]) << 8; // fall-through
  case  5: k2 ^= static_cast<unsigned int>(tail[ 4]) << 0;
           k2 *= c2; k2  = ROTL32(k2,16); k2 *= c3; h2 ^= k2;

  case  4: k1 ^= static_cast<unsigned int>(tail[ 3]) << 24; // fall-through
  case  3: k1 ^= static_cast<unsigned int>(tail[ 2]) << 16; // fall-through
  case  2: k1 ^= static_cast<unsigned int>(tail[ 1]) << 8; // fall-through
  case  1: k1 ^= static_cast<unsigned int>(tail[ 0]) << 0;
           k1 *= c1; k1  = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
  break;
  default:
  break;
  };

  //----------
  // finalization

  h1 ^= static_cast<unsigned int>(len); h2 ^= static_cast<unsigned int>(len); h3 ^= static_cast<unsigned int>(len); h4 ^= static_cast<unsigned int>(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;

  (static_cast<uint32_t*>(out))[0] = h1;
  (static_cast<uint32_t*>(out))[1] = h2;
  (static_cast<uint32_t*>(out))[2] = h3;
  (static_cast<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 = reinterpret_cast<const uint8_t*>(key);
  const int nblocks = len / 16;

  uint64_t h1 = seed;
  uint64_t h2 = seed;

  const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
  const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);

  //----------
  // body

  const uint64_t * blocks = reinterpret_cast<const uint64_t *>(data);

  for(int i = 0; i < nblocks; i++) {
    uint64_t k1 = getblock64(blocks,i*2+0);
    uint64_t k2 = getblock64(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 = (data + nblocks*16);

  uint64_t k1 = 0;
  uint64_t k2 = 0;

  switch(len & 15) {
    case 15: k2 ^= (static_cast<uint64_t>(tail[14])) << 48; // fall-through
    case 14: k2 ^= (static_cast<uint64_t>(tail[13])) << 40; // fall-through
    case 13: k2 ^= (static_cast<uint64_t>(tail[12])) << 32; // fall-through
    case 12: k2 ^= (static_cast<uint64_t>(tail[11])) << 24; // fall-through
    case 11: k2 ^= (static_cast<uint64_t>(tail[10])) << 16; // fall-through
    case 10: k2 ^= (static_cast<uint64_t>(tail[ 9])) << 8; // fall-through
    case  9: k2 ^= (static_cast<uint64_t>(tail[ 8])) << 0;
             k2 *= c2; k2  = ROTL64(k2,33); k2 *= c1; h2 ^= k2;

    case  8: k1 ^= (static_cast<uint64_t>(tail[ 7])) << 56; // fall-through
    case  7: k1 ^= (static_cast<uint64_t>(tail[ 6])) << 48; // fall-through
    case  6: k1 ^= (static_cast<uint64_t>(tail[ 5])) << 40; // fall-through
    case  5: k1 ^= (static_cast<uint64_t>(tail[ 4])) << 32; // fall-through
    case  4: k1 ^= (static_cast<uint64_t>(tail[ 3])) << 24; // fall-through
    case  3: k1 ^= (static_cast<uint64_t>(tail[ 2])) << 16; // fall-through
    case  2: k1 ^= (static_cast<uint64_t>(tail[ 1])) << 8; // fall-through
    case  1: k1 ^= (static_cast<uint64_t>(tail[ 0])) << 0;
             k1 *= c1; k1  = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
    break;
    default:
    break;
  };

  //----------
  // finalization

  h1 ^= static_cast<unsigned int>(len); h2 ^= static_cast<unsigned int>(len);

  h1 += h2;
  h2 += h1;

  h1 = fmix64(h1);
  h2 = fmix64(h2);

  h1 += h2;
  h2 += h1;

  (static_cast<uint64_t*>(out))[0] = h1;
  (static_cast<uint64_t*>(out))[1] = h2;
}

//-----------------------------------------------------------------------------
/* Test for GCC > 6.0.0 */
#if GCC_VERSION > 60000
#pragma GCC diagnostic pop
#else
// Otherwise, turn the warning back on manually.
#pragma GCC diagnostic warning "-Wimplicit-fallthrough"
#endif


code:
//-----------------------------------------------------------------------------
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.

#ifndef _MURMURHASH3_H_
#define _MURMURHASH3_H_

//-----------------------------------------------------------------------------
// Platform-specific functions and macros

// Microsoft Visual Studio

#if defined(_MSC_VER) && (_MSC_VER < 1600)

typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;

// Other compilers

#else	// defined(_MSC_VER)

#include <stdint.h>

#endif // !defined(_MSC_VER)

//-----------------------------------------------------------------------------

void MurmurHash3_x86_32  ( const void * key, int len, uint32_t seed, void * out );

void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out );

void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out );

//-----------------------------------------------------------------------------

#endif // _MURMURHASH3_H_


code:
#ifndef _MMAN_H_
#define _MMAN_H_
#ifdef _WIN32
/* Protections */
#define PROT_NONE       0x00    /* no permissions */
#define PROT_READ       0x01    /* pages can be read */
#define PROT_WRITE      0x02    /* pages can be written */
#define PROT_EXEC       0x04    /* pages can be executed */

/* Sharing type and options */
#define MAP_SHARED      0x0001          /* share changes */
#define MAP_PRIVATE     0x0002          /* changes are private */
#define MAP_COPY        MAP_PRIVATE     /* Obsolete */
#define MAP_FIXED        0x0010 /* map addr must be exactly as requested */
#define MAP_RENAME       0x0020 /* Sun: rename private pages to file */
#define MAP_NORESERVE    0x0040 /* Sun: don't reserve needed swap area */
#define MAP_INHERIT      0x0080 /* region is retained after exec */
#define MAP_NOEXTEND     0x0100 /* for MAP_FILE, don't change file size */
#define MAP_HASSEMAPHORE 0x0200 /* region may contain semaphores */
#define MAP_STACK        0x0400 /* region grows down, like a stack */

/* Error returned from mmap() */
#define MAP_FAILED      ((void *)-1)

/* Flags to msync */
#define MS_ASYNC        0x01    /* perform asynchronous writes */
#define MS_SYNC         0x02    /* perform synchronous writes */
#define MS_INVALIDATE   0x04    /* invalidate cached data */

/* File modes for 'open' not defined in MinGW32  (not used by mmap) */
#ifndef S_IWGRP
#define S_IWGRP 0
#define S_IRGRP 0
#define S_IROTH 0
#endif

/**
 * Map a file to a memory region
 */
void *mmap(void *addr, unsigned int len, int prot, int flags, int fd, unsigned int offset);

/**
 * Unmap a memory region
 */
int munmap(void *addr, int len);

/**
 * Synchronize a mapped region
 */
int msync(char *addr, int len, int flags);
#endif
#endif	/* _MMAN_H_ */


code:
#ifdef _WIN32 /* this file becomes blank on non-NT builds */
#include <stdlib.h>
#include <windows.h>
#include <io.h>
#include <errno.h>
#include "mman.h"

static const char id[]="$Id: mmap.c 107 2017-11-17 21:34:29Z despair $";

/**
 * @brief Map a file to a memory region
 *
 * This function emulates the POSIX mmap() using CreateFileMapping() and
 * MapViewOfFile()
 *
 * @param addr the suggested start address (if != 0)
 * @param len length of the region
 * @param prot region accesibility, bitwise OR of PROT_READ, PROT_WRITE, PROT_EXEC
 * @param flags mapping type and options (ignored)
 * @param fd object to be mapped into memory
 * @param offset offset into mapped object
 * @return pointer to the memory region, or NULL in case of error
 */
void *mmap(void *addr, unsigned int len, int prot, int flags, int fd, unsigned int offset)
{
	DWORD wprot;
	DWORD waccess;
	HANDLE h;
	void *region;

	/* Translate read/write/exec flags into WIN32 constants */
	switch (prot) {
	case PROT_READ:
		wprot = PAGE_READONLY;
		break;
	case PROT_EXEC:
		wprot = PAGE_EXECUTE_READ;
		break;
	case PROT_READ | PROT_EXEC:
		wprot = PAGE_EXECUTE_READ;
		break;
	case PROT_WRITE:
		wprot = PAGE_READWRITE;
		break;
	case PROT_READ | PROT_WRITE:
		wprot = PAGE_READWRITE;
		break;
	case PROT_READ | PROT_WRITE | PROT_EXEC:
		wprot = PAGE_EXECUTE_READWRITE;
		break;
	case PROT_WRITE | PROT_EXEC:
		wprot = PAGE_EXECUTE_READWRITE;
		break;
	}

	/* Obtaing handle to map region */
	h = CreateFileMapping((HANDLE) _get_osfhandle(fd), 0, wprot, 0, len, 0);
	if (h == NULL) {
		DWORD error = GetLastError();

		/* Try and translate some error codes */
		switch (error) {
		case ERROR_ACCESS_DENIED:
		case ERROR_INVALID_ACCESS:
			errno = EACCES;
			break;
		case ERROR_OUTOFMEMORY:
		case ERROR_NOT_ENOUGH_MEMORY:
			errno = ENOMEM;
			break;
		default:
			errno = EINVAL;
			break;
		}
		return MAP_FAILED;
	}

	/* Translate sharing options into WIN32 constants */
	switch (wprot) {
	case PAGE_READONLY:
		waccess = FILE_MAP_READ;
		break;
	case PAGE_READWRITE:
		waccess = FILE_MAP_WRITE;
		break;
	}

	/* Map file and return pointer */
	region = MapViewOfFile(h, waccess, 0, 0, 0);
	if (region == NULL) {
		DWORD error = GetLastError();

		/* Try and translate some error codes */
		switch (error) {
		case ERROR_ACCESS_DENIED:
		case ERROR_INVALID_ACCESS:
			errno = EACCES;
			break;
		case ERROR_INVALID_HANDLE:
			errno = EBADF;
			break;
		default:
			errno = EINVAL;
			break;
		}
		CloseHandle(h);
		return MAP_FAILED;
	}
	CloseHandle(h); /* ok to call UnmapViewOfFile after this */

	/* All fine */
	return region;
}

/**
 * @brief Unmap a memory region
 *
 * This is a wrapper around UnmapViewOfFile in the win32 API
 *
 * @param addr start address
 * @param len length of the region
 * @return 0 for success, -1 for error
 */
int munmap(void *addr, int len)
{
	if (UnmapViewOfFile(addr)) {
		return 0;
	}
	else {
		errno = EINVAL;
		return -1;
	}
}

/**
 * Synchronize a mapped region
 *
 * This is a wrapper around FlushViewOfFile
 *
 * @param addr start address
 * @param len number of bytes to flush
 * @param flags sync options -- currently ignored
 * @return 0 for success, -1 for error
 */
int msync(char *addr, int len, int flags)
{
	if (FlushViewOfFile(addr, len) == 0) {
		DWORD error = GetLastError();

		/* Try and translate some error codes */
		switch (error) {
		case ERROR_INVALID_PARAMETER:
			errno = EINVAL;
			break;
		case ERROR_WRITE_FAULT:
			errno = EIO;
			break;
		default:
			errno = EINVAL;
			break;
		}
		return -1;
	}

	/* Success */
	return 0;
}
#endif


code:
// ©2008-2017 despair <despair@netrunner.cc>
#ifndef NETRUNNER_H
#define NETRUNNER_H
#include "Murmur3.h"
#include <string>
#include <unordered_map>
#include <utility>
#include <algorithm>
#include <limits>
#include <iostream>
#include <cstring>
#include "tlsf.h"

// let's try fast strings
namespace ntr{

    template <class T>
    class TLSFAlloc {
    public:
      typedef T value_type;
      typedef T* pointer;
      typedef const T* const_pointer;
      typedef T& reference;
      typedef const T& const_reference;
      typedef std::size_t size_type;
      typedef std::ptrdiff_t difference_type;

      template <class U>
      struct rebind {
        typedef TLSFAlloc<U> other;
      };

      pointer address (reference value) const {
        return &value;
      }
      const_pointer address (const_reference value) const {
        return &value;
      }

      // these are the constructors for same: had I not ported sbrk(2) to winnt,
      // the constructor would have generated a memory pool from above.
      TLSFAlloc() throw() {}
      TLSFAlloc(const TLSFAlloc&) throw() {}
      template <class U> TLSFAlloc(const TLSFAlloc<U>&) throw() {}
      ~TLSFAlloc() throw() {}

      // placement new
      static void* operator new (std::size_t size, void*) {
          // because this is a static, it can't access this->allocate
          // so I've jsut copied allocate here
  #ifdef DEBUG_TLSF_CPP
          // print message and allocate memory with 2LSF
          std::cerr << "allocate " << size << " element(s)" << " of size " << sizeof(T) << std::endl;
          pointer ret = static_cast<pointer>(tlsf_malloc(size * sizeof(T)));
          std::cerr << " allocated at: " << (void*)ret << std::endl;
  #else
          pointer ret = static_cast<pointer>(tlsf_malloc(size * sizeof(T)));
  #endif
          return ret;
      }

      // destroy elements of initialized storage p
      void destroy (pointer p) {
        p->~T();
      }

      // return maximum number of elements that can be allocated
      size_type max_size() const throw() {
        return std::numeric_limits<std::size_t>::max() / sizeof(T);
      }

      // allocate but don't initialize num elements of type T
      pointer allocate(size_type num, const void* = 0) {
  #ifdef DEBUG_TLSF_CPP
        // print message and allocate memory with 2LSF
        std::cerr << "allocate " << num << " element(s)" << " of size " << sizeof(T) << std::endl;
        pointer ret = (pointer)(tlsf_malloc(num*sizeof(T)));
        std::cerr << " allocated at: " << (void*)ret << std::endl; return ret;
  #else
        pointer ret = static_cast<pointer>(tlsf_malloc(num*sizeof(T)));
        return ret;
  #endif
      }
      // initialize elements of allocated storage p with value value
      // using placement new (defined here)
      void construct (pointer p, const T& value) {
        new (reinterpret_cast<void*>(p))T(value);
      }

      // deallocate storage p of deleted elements
      void deallocate(pointer p, size_type num) {
  #ifdef DEBUG_TLSF_CPP
         // print message and deallocate memory with global delete
         std::cerr << "deallocate " << num << " element(s)"  << " of size " << sizeof(T) << " at: " << (void*)p << std::endl;
  #endif
         tlsf_free(reinterpret_cast<void*>(p));
       }
    };

     // return that all specializations of this allocator are interchangeable
     template <class T1, class T2> bool operator== (const TLSFAlloc<T1>&,const TLSFAlloc<T2>&) throw() { return true; }
     template <class T1, class T2> bool operator!= (const TLSFAlloc<T1>&, const TLSFAlloc<T2>&) throw() { return false; }

     template <class CharT>
     using fast_basic_string = std::basic_string<CharT, std::char_traits<CharT>, TLSFAlloc<CharT>>;
     using fast_string = fast_basic_string<char>;

     // NT uses UTF-16
     using fast_hexstring = fast_basic_string<wchar_t>;

     // POSIX demands 32-bit Unicode
     using fast_u32string = fast_basic_string<char32_t>;

     // Depending on yer environment, these may or may not be meaningful
     using fast_octstring = fast_basic_string<unsigned char>;
     using fast_sepstring = fast_basic_string<signed char>;

    class StringHash{
    public:
        std::size_t operator() (const fast_string& s) const {
            size_t out = 0;
            // 32-bit hash only, all others overflow. RIP AMD64 users...
            MurmurHash3_x86_32 ( &s, sizeof(s), 7904542L, &out );
            return out;
        }
    };
    class StringComparison{
    public:
        bool operator ()(const fast_string &a, const fast_string &b) const {
            int i = strcmp(a.c_str(), b.c_str());
            if (!i){
                return true;
            }
            else{
                return false;
            }
        }
    };

    typedef std::unordered_map<fast_string,fast_string,StringHash,StringComparison,TLSFAlloc<std::pair<const fast_string, fast_string>>> stringmap;
}
#endif


code:
/*
 * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
 * All rights reserved
 *
 * "THE BEER-WARE LICENSE" (Revision 42):
 * Sergey Lyubka wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.
 */

 #include <stdio.h>
 #include <assert.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>

 #include "slre.h"

 enum {END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL,
     STAR, PLUS, STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT};

 static struct {
     const char	*name;
     int		narg;
     const char	*flags;
 } opcodes[] = {
     {"END",		0, ""},		/* End of code block or program	*/
     {"BRANCH",	2, "oo"},	/* Alternative operator, "|"	*/
     {"ANY",		0, ""},		/* Match any character, "."	*/
     {"EXACT",	2, "d"},	/* Match exact string		*/
     {"ANYOF",	2, "D"},	/* Match any from set, "[]"	*/
     {"ANYBUT",	2, "D"},	/* Match any but from set, "[^]"*/
     {"OPEN ",	1, "i"},	/* Capture start, "("		*/
     {"CLOSE",	1, "i"},	/* Capture end, ")"		*/
     {"BOL",		0, ""},		/* Beginning of string, "^"	*/
     {"EOL",		0, ""},		/* End of string, "$"		*/
     {"STAR",	1, "o"},	/* Match zero or more times "*"	*/
     {"PLUS",	1, "o"},	/* Match one or more times, "+"	*/
     {"STARQ",	1, "o"},	/* Non-greedy STAR,  "*?"	*/
     {"PLUSQ",	1, "o"},	/* Non-greedy PLUS, "+?"	*/
     {"QUEST",	1, "o"},	/* Match zero or one time, "?"	*/
     {"SPACE",	0, ""},		/* Match whitespace, "\s"	*/
     {"NONSPACE",	0, ""},		/* Match non-space, "\S"	*/
     {"DIGIT",	0, ""}		/* Match digit, "\d"		*/
 };

 /*
  * Commands and operands are all unsigned char (1 byte long). All code offsets
  * are relative to current address, and positive (always point forward). Data
  * offsets are absolute. Commands with operands:
  *
  * BRANCH offset1 offset2
  *	Try to match the code block that follows the BRANCH instruction
  *	(code block ends with END). If no match, try to match code block that
  *	starts at offset1. If either of these match, jump to offset2.
  *
  * EXACT data_offset data_length
  *	Try to match exact string. String is recorded in data section from
  *	data_offset, and has length data_length.
  *
  * OPEN capture_number
  * CLOSE capture_number
  *	If the user have passed 'struct cap' array for captures, OPEN
  *	records the beginning of the matched substring (cap->ptr), CLOSE
  *	sets the length (cap->len) for respective capture_number.
  *
  * STAR code_offset
  * PLUS code_offset
  * QUEST code_offset
  *	*, +, ?, respectively. Try to gobble as much as possible from the
  *	matched buffer, until code block that follows these instructions
  *	matches. When the longest possible string is matched,
  *	jump to code_offset
  *
  * STARQ, PLUSQ are non-greedy versions of STAR and PLUS.
  */

 static const char *meta_chars = "|.^$*+?()[\\";

 static void
 print_character_set(FILE *fp, const unsigned char *p, int len)
 {
     int	i;

     for (i = 0; i < len; i++) {
         if (i > 0)
             (void) fputc(',', fp);
         if (p[i] == 0) {
             i++;
             if (p[i] == 0)
                 (void) fprintf(fp, "\\x%02x", p[i]);
             else
                 (void) fprintf(fp, "%s", opcodes[p[i]].name);
         } else if (isprint(p[i])) {
             (void) fputc(p[i], fp);
         } else {
             (void) fprintf(fp,"\\x%02x", p[i]);
         }
     }
 }

 void
 slre_dump(const struct slre *r, FILE *fp)
 {
     int	i, j, ch, op, pc;

     for (pc = 0; pc < r->code_size; pc++) {

         op = r->code[pc];
         (void) fprintf(fp, "%3d %s ", pc, opcodes[op].name);

         for (i = 0; opcodes[op].flags[i] != '\0'; i++)
             switch (opcodes[op].flags[i]) {
             case 'i':
                 (void) fprintf(fp, "%d ", r->code[pc + 1]);
                 pc++;
                 break;
             case 'o':
                 (void) fprintf(fp, "%d ",
                     pc + r->code[pc + 1] - i);
                 pc++;
                 break;
             case 'D':
                 print_character_set(fp, r->data +
                     r->code[pc + 1], r->code[pc + 2]);
                 pc += 2;
                 break;
             case 'd':
                 (void) fputc('"', fp);
                 for (j = 0; j < r->code[pc + 2]; j++) {
                     ch = r->data[r->code[pc + 1] + j];
                     if (isprint(ch))
                         (void) fputc(ch, fp);
                     else
                         (void) fprintf(fp,"\\x%02x",ch);
                 }
                 (void) fputc('"', fp);
                 pc += 2;
                 break;
             }

         (void) fputc('\n', fp);
     }
 }

 static void
 set_jump_offset(struct slre *r, int pc, int offset)
 {
     assert(offset < r->code_size);

     if (r->code_size - offset > 0xff) {
         r->err_str = "Jump offset is too big";
     } else {
         r->code[pc] = (unsigned char) (r->code_size - offset);
     }
 }

 static void
 emit(struct slre *r, int code)
 {
     if (r->code_size >= (int) (sizeof(r->code) / sizeof(r->code[0])))
         r->err_str = "RE is too long (code overflow)";
     else
         r->code[r->code_size++] = (unsigned char) code;
 }

 static void
 store_char_in_data(struct slre *r, int ch)
 {
     if (r->data_size >= (int) sizeof(r->data))
         r->err_str = "RE is too long (data overflow)";
     else
         r->data[r->data_size++] = ch;
 }

 static void
 exact(struct slre *r, const char **re)
 {
     int	old_data_size = r->data_size;

     while (**re != '\0' && (strchr(meta_chars, **re)) == NULL)
         store_char_in_data(r, *(*re)++);

     emit(r, EXACT);
     emit(r, old_data_size);
     emit(r, r->data_size - old_data_size);
 }

 static int
 get_escape_char(const char **re)
 {
     int	res;

     switch (*(*re)++) {
     case 'n':	res = '\n';		break;
     case 'r':	res = '\r';		break;
     case 't':	res = '\t';		break;
     case '0':	res = 0;		break;
     case 'S':	res = NONSPACE << 8;	break;
     case 's':	res = SPACE << 8;	break;
     case 'd':	res = DIGIT << 8;	break;
     default:	res = (*re)[-1];	break;
     }

     return (res);
 }

 static void
 anyof(struct slre *r, const char **re)
 {
     int	esc, old_data_size = r->data_size, op = ANYOF;

     if (**re == '^') {
         op = ANYBUT;
         (*re)++;
     }

     while (**re != '\0')

         switch (*(*re)++) {
         case ']':
             emit(r, op);
             emit(r, old_data_size);
             emit(r, r->data_size - old_data_size);
             return;
             /* NOTREACHED */
             break;
         case '\\':
             esc = get_escape_char(re);
             if ((esc & 0xff) == 0) {
                 store_char_in_data(r, 0);
                 store_char_in_data(r, esc >> 8);
             } else {
                 store_char_in_data(r, esc);
             }
             break;
         default:
             store_char_in_data(r, (*re)[-1]);
             break;
         }

     r->err_str = "No closing ']' bracket";
 }

 static void
 relocate(struct slre *r, int begin, int shift)
 {
     emit(r, END);
     memmove(r->code + begin + shift, r->code + begin, r->code_size - begin);
     r->code_size += shift;
 }

 static void
 quantifier(struct slre *r, int prev, int op)
 {
     if (r->code[prev] == EXACT && r->code[prev + 2] > 1) {
         r->code[prev + 2]--;
         emit(r, EXACT);
         emit(r, r->code[prev + 1] + r->code[prev + 2]);
         emit(r, 1);
         prev = r->code_size - 3;
     }
     relocate(r, prev, 2);
     r->code[prev] = op;
     set_jump_offset(r, prev + 1, prev);
 }

 static void
 exact_one_char(struct slre *r, int ch)
 {
     emit(r, EXACT);
     emit(r, r->data_size);
     emit(r, 1);
     store_char_in_data(r, ch);
 }

 static void
 fixup_branch(struct slre *r, int fixup)
 {
     if (fixup > 0) {
         emit(r, END);
         set_jump_offset(r, fixup, fixup - 2);
     }
 }

 static void
 compile(struct slre *r, const char **re)
 {
     int	op, esc, branch_start, last_op, fixup, cap_no, level;

     fixup = 0;
     level = r->num_caps;
     branch_start = last_op = r->code_size;

     for (;;)
         switch (*(*re)++) {
         case '\0':
             (*re)--;
             return;
             /* NOTREACHED */
             break;
         case '^':
             emit(r, BOL);
             break;
         case '$':
             emit(r, EOL);
             break;
         case '.':
             last_op = r->code_size;
             emit(r, ANY);
             break;
         case '[':
             last_op = r->code_size;
             anyof(r, re);
             break;
         case '\\':
             last_op = r->code_size;
             esc = get_escape_char(re);
             if (esc & 0xff00) {
                 emit(r, esc >> 8);
             } else {
                 exact_one_char(r, esc);
             }
             break;
         case '(':
             last_op = r->code_size;
             cap_no = ++r->num_caps;
             emit(r, OPEN);
             emit(r, cap_no);

             compile(r, re);
             if (*(*re)++ != ')') {
                 r->err_str = "No closing bracket";
                 return;
             }

             emit(r, CLOSE);
             emit(r, cap_no);
             break;
         case ')':
             (*re)--;
             fixup_branch(r, fixup);
             if (level == 0) {
                 r->err_str = "Unbalanced brackets";
                 return;
             }
             return;
             /* NOTREACHED */
             break;
         case '+':
         case '*':
             op = (*re)[-1] == '*' ? STAR: PLUS;
             if (**re == '?') {
                 (*re)++;
                 op = op == STAR ? STARQ : PLUSQ;
             }
             quantifier(r, last_op, op);
             break;
         case '?':
             quantifier(r, last_op, QUEST);
             break;
         case '|':
             fixup_branch(r, fixup);
             relocate(r, branch_start, 3);
             r->code[branch_start] = BRANCH;
             set_jump_offset(r, branch_start + 1, branch_start);
             fixup = branch_start + 2;
             r->code[fixup] = 0xff;
             break;
         default:
             (*re)--;
             last_op = r->code_size;
             exact(r, re);
             break;
         }
 }

 int
 slre_compile(struct slre *r, const char *re)
 {
     r->err_str = NULL;
     r->code_size = r->data_size = r->num_caps = r->anchored = 0;

     if (*re == '^')
         r->anchored++;

     emit(r, OPEN);	/* This will capture what matches full RE */
     emit(r, 0);

     while (*re != '\0')
         compile(r, &re);

     if (r->code[2] == BRANCH)
         fixup_branch(r, 4);

     emit(r, CLOSE);
     emit(r, 0);
     emit(r, END);

     return (r->err_str == NULL ? 1 : 0);
 }

 static int match(const struct slre *, int,
         const char *, int, int *, struct cap *);

 static void
 loop_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs)
 {
     int	saved_offset, matched_offset;

     saved_offset = matched_offset = *ofs;

     while (match(r, pc + 2, s, len, ofs, NULL)) {
         saved_offset = *ofs;
         if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL))
             matched_offset = saved_offset;
         *ofs = saved_offset;
     }

     *ofs = matched_offset;
 }

 static void
 loop_non_greedy(const struct slre *r, int pc, const char *s,int len, int *ofs)
 {
     int	saved_offset = *ofs;

     while (match(r, pc + 2, s, len, ofs, NULL)) {
         saved_offset = *ofs;
         if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL))
             break;
     }

     *ofs = saved_offset;
 }

 static int
 is_any_of(const unsigned char *p, int len, const char *s, int *ofs)
 {
     int	i, ch;

     ch = s[*ofs];

     for (i = 0; i < len; i++)
         if (p[i] == ch) {
             (*ofs)++;
             return (1);
         }

     return (0);
 }

 static int
 is_any_but(const unsigned char *p, int len, const char *s, int *ofs)
 {
     int	i, ch;

     ch = s[*ofs];

     for (i = 0; i < len; i++)
         if (p[i] == ch)
             return (0);

     (*ofs)++;
     return (1);
 }

 static int
 match(const struct slre *r, int pc, const char *s, int len,
         int *ofs, struct cap *caps)
 {
     int	n, saved_offset, res = 1;

     while (res && r->code[pc] != END) {

         assert(pc < r->code_size);
         assert(pc < (int) (sizeof(r->code) / sizeof(r->code[0])));

         switch (r->code[pc]) {
         case BRANCH:
             saved_offset = *ofs;
             res = match(r, pc + 3, s, len, ofs, caps);
             if (res == 0) {
                 *ofs = saved_offset;
                 res = match(r, pc + r->code[pc + 1],
                     s, len, ofs, caps);
             }
             pc += r->code[pc + 2];
             break;
         case EXACT:
             res = 0;
             n = r->code[pc + 2];	/* String length */
             if (n <= len - *ofs && !memcmp(s + *ofs, r->data +
                 r->code[pc + 1], n)) {
                 (*ofs) += n;
                 res = 1;
             }
             pc += 3;
             break;
         case QUEST:
             res = 1;
             saved_offset = *ofs;
             if (!match(r, pc + 2, s, len, ofs, caps))
                 *ofs = saved_offset;
             pc += r->code[pc + 1];
             break;
         case STAR:
             res = 1;
             loop_greedy(r, pc, s, len, ofs);
             pc += r->code[pc + 1];
             break;
         case STARQ:
             res = 1;
             loop_non_greedy(r, pc, s, len, ofs);
             pc += r->code[pc + 1];
             break;
         case PLUS:
             if ((res = match(r, pc + 2, s, len, ofs, caps)) == 0)
                 break;

             loop_greedy(r, pc, s, len, ofs);
             pc += r->code[pc + 1];
             break;
         case PLUSQ:
             if ((res = match(r, pc + 2, s, len, ofs, caps)) == 0)
                 break;

             loop_non_greedy(r, pc, s, len, ofs);
             pc += r->code[pc + 1];
             break;
         case SPACE:
             res = 0;
             if (*ofs < len && isspace(((unsigned char *)s)[*ofs])) {
                 (*ofs)++;
                 res = 1;
             }
             pc++;
             break;
         case NONSPACE:
             res = 0;
             if (*ofs <len && !isspace(((unsigned char *)s)[*ofs])) {
                 (*ofs)++;
                 res = 1;
             }
             pc++;
             break;
         case DIGIT:
             res = 0;
             if (*ofs < len && isdigit(((unsigned char *)s)[*ofs])) {
                 (*ofs)++;
                 res = 1;
             }
             pc++;
             break;
         case ANY:
             res = 0;
             if (*ofs < len) {
                 (*ofs)++;
                 res = 1;
             }
             pc++;
             break;
         case ANYOF:
             res = 0;
             if (*ofs < len)
                 res = is_any_of(r->data + r->code[pc + 1],
                     r->code[pc + 2], s, ofs);
             pc += 3;
             break;
         case ANYBUT:
             res = 0;
             if (*ofs < len)
                 res = is_any_but(r->data + r->code[pc + 1],
                     r->code[pc + 2], s, ofs);
             pc += 3;
             break;
         case BOL:
             res = *ofs == 0 ? 1 : 0;
             pc++;
             break;
         case EOL:
             res = *ofs == len ? 1 : 0;
             pc++;
             break;
         case OPEN:
             if (caps != NULL)
                 caps[r->code[pc + 1]].ptr = s + *ofs;
             pc += 2;
             break;
         case CLOSE:
             if (caps != NULL)
                 caps[r->code[pc + 1]].len = (s + *ofs) -
                     caps[r->code[pc + 1]].ptr;
             pc += 2;
             break;
         case END:
             pc++;
             break;
         default:
             printf("unknown cmd (%d) at %d\n", r->code[pc], pc);
             assert(0);
             break;
         }
     }

     return (res);
 }

 int
 slre_match(const struct slre *r, const char *buf, int len,
         struct cap *caps)
 {
     int	i, ofs = 0, res = 0;

     if (r->anchored) {
         res = match(r, 0, buf, len, &ofs, caps);
     } else {
         for (i = 0; i < len && res == 0; i++) {
             ofs = i;
             res = match(r, 0, buf, len, &ofs, caps);
         }
     }

     return (res);
 }

 #ifdef TEST
 int main(int argc, char *argv[])
 {
     struct slre	slre;
     struct cap	caps[20];
     char		data[1 * 1024 * 1024];
     FILE		*fp;
     int		i, count, res, len;

     if (argc < 3) {
         printf("Usage: %s 'slre' <file> [count]\n", argv[0]);
     } else if ((fp = fopen(argv[2], "rb")) == NULL) {
         printf("Error: cannot open %s:%s\n", argv[2], strerror(errno));
     } else if (!slre_compile(&slre, argv[1])) {
         printf("Error compiling slre: %s\n", slre.err_str);
     } else {
         slre_dump(&slre, stderr);

         (void) memset(caps, 0, sizeof(caps));

         /* Read first 128K of file */
         len = fread(data, 1, sizeof(data), fp);
         (void) fclose(fp);

         res = 0;
         count = argc > 3 ? atoi(argv[3]) : 1;
         for (i = 0; i < count; i++)
             res = slre_match(&slre, data, len, caps);

         printf("Result: %d\n", res);

         for (i = 0; i < 20; i++)
             if (caps[i].len > 0)
                 printf("Substring %d: [%.*s]\n", i,
                     caps[i].len, caps[i].ptr);
     }

     return (0);
 }
 #endif /* TEST */


code:
/*
 * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
 * All rights reserved
 *
 * "THE BEER-WARE LICENSE" (Revision 42):
 * Sergey Lyubka wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.
 */

/*
 * This is a regular expression library that implements a subset of Perl RE.
 * Please refer to http://slre.sourceforge.net for detailed description.
 *
 * Usage example (parsing HTTP request):
 *
 * struct slre	slre;
 * struct cap	captures[4 + 1];  // Number of braket pairs + 1
 * ...
 *
 * slre_compile(&slre,"^(GET|POST) (\S+) HTTP/(\S+?)\r\n");
 *
 * if (slre_match(&slre, buf, len, captures)) {
 *	printf("Request line length: %d\n", captures[0].len);
 *	printf("Method: %.*s\n", captures[1].len, captures[1].ptr);
 *	printf("URI: %.*s\n", captures[2].len, captures[2].ptr);
 * }
 *
 * Supported syntax:
 *	^		Match beginning of a buffer
 *	$		Match end of a buffer
 *	()		Grouping and substring capturing
 *	[...]		Match any character from set
 *	[^...]		Match any character but ones from set
 *	\s		Match whitespace
 *	\S		Match non-whitespace
 *	\d		Match decimal digit
 *	\r		Match carriage return
 *	\n		Match newline
 *	+		Match one or more times (greedy)
 *	+?		Match one or more times (non-greedy)
 *	*		Match zero or more times (greedy)
 *	*?		Match zero or more times (non-greedy)
 *	?		Match zero or once
 *	\xDD		Match byte with hex value 0xDD
 *	\meta		Match one of the meta character: ^$().[*+?\
 */

#ifndef SLRE_HEADER_DEFINED
#define	SLRE_HEADER_DEFINED

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Compiled regular expression
 */
struct slre {
	unsigned char	code[256];
	unsigned char	data[256];
	int		code_size;
	int		data_size;
	int		num_caps;	/* Number of bracket pairs	*/
	int		anchored;	/* Must match from string start	*/
	const char	*err_str;	/* Error string			*/
};

/*
 * Captured substring
 */
struct cap {
	const char	*ptr;		/* Pointer to the substring	*/
	int		len;		/* Substring length		*/
};

/*
 * Compile regular expression. If success, 1 is returned.
 * If error, 0 is returned and slre.err_str points to the error message.
 */
int slre_compile(struct slre *, const char *re);

/*
 * Return 1 if match, 0 if no match.
 * If `captured_substrings' array is not NULL, then it is filled with the
 * values of captured substrings. captured_substrings[0] element is always
 * a full matched substring. The round bracket captures start from
 * captured_substrings[1].
 * It is assumed that the size of captured_substrings array is enough to
 * hold all captures. The caller function must make sure it is! So, the
 * array_size = number_of_round_bracket_pairs + 1
 */
int slre_match(const struct slre *, const char *buf, int buf_len,
    struct cap *captured_substrings);

#ifdef __cplusplus
}
#endif

#endif /* SLRE_HEADER_DEFINED */


code:
#ifndef _TARGET_H_
#define _TARGET_H_

#if !defined(_WIN32) || defined(USE_PTHREAD_EVEN_ON_WINNT)
#include <pthread.h>
#define TLSF_MLOCK_T            pthread_mutex_t
#define TLSF_CREATE_LOCK(l)     pthread_mutex_init (l, NULL)
#define TLSF_DESTROY_LOCK(l)    pthread_mutex_destroy(l)
#define TLSF_ACQUIRE_LOCK(l)    pthread_mutex_lock(l)
#define TLSF_RELEASE_LOCK(l)    pthread_mutex_unlock(l)
#elif defined(_WIN32) && !defined(USE_PTHREAD_EVEN_ON_WINNT)
#include <windows.h>
#define TLSF_MLOCK_T            CRITICAL_SECTION
#define TLSF_CREATE_LOCK(l)     InitializeCriticalSection(l)
#define TLSF_DESTROY_LOCK(l)    DeleteCriticalSection(l)
#define TLSF_ACQUIRE_LOCK(l)    EnterCriticalSection(l)
#define TLSF_RELEASE_LOCK(l)    LeaveCriticalSection(l)
#else
/* Some other platform. What are YOUR synchronisation primitives? */
#endif

#endif


code:
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Two Levels Segregate Fit memory allocator (TLSF)
 * Version 2.4.6
 *
 * Written by Miguel Masmano Tello <mimastel@doctor.upv.es>
 *
 * Thanks to Ismael Ripoll for his suggestions and reviews
 *
 * Copyright (C) 2008, 2007, 2006, 2005, 2004
 *
 * This code is released using a dual license strategy: GPL/LGPL
 * You can choose the licence that better fits your requirements.
 *
 * Released under the terms of the GNU General Public License Version 2.0
 * Released under the terms of the GNU Lesser General Public License Version 2.1
 *
 */

/*
 * Code contributions:
 *
 * (Jul 28 2007)  Herman ten Brugge <hermantenbrugge@home.nl>:
 *
 * - Add 64 bit support. It now runs on x86_64 and solaris64.
 * - I also tested this on vxworks/32and solaris/32 and i386/32 processors.
 * - Remove assembly code. I could not measure any performance difference
 *   on my core2 processor. This also makes the code more portable.
 * - Moved defines/typedefs from tlsf.h to tlsf.c
 * - Changed MIN_BLOCK_SIZE to sizeof (free_ptr_t) and BHDR_OVERHEAD to
 *   (sizeof (bhdr_t) - MIN_BLOCK_SIZE). This does not change the fact
 *    that the minumum size is still sizeof
 *   (bhdr_t).
 * - Changed all C++ comment style to C style. (// -> /.* ... *./)
 * - Used ls_bit instead of ffs and ms_bit instead of fls. I did this to
 *   avoid confusion with the standard ffs function which returns
 *   different values.
 * - Created set_bit/clear_bit fuctions because they are not present
 *   on x86_64.
 * - Added locking support + extra file target.h to show how to use it.
 * - Added get_used_size function (REMOVED in 2.4)
 * - Added rtl_realloc and rtl_calloc function
 * - Implemented realloc clever support.
 * - Added some test code in the example directory.
 * - Bug fixed (discovered by the rockbox project: www.rockbox.org).
 *
 * (Oct 23 2006) Adam Scislowicz:
 *
 * - Support for ARMv5 implemented
 *
 * (22 Aug 2017) despair:
 * - Inlined implementation of sbrk(3) for WinNT and Win32s
 */

/*#define USE_SBRK        (0) */
/*#define USE_MMAP        (0) */

#ifndef USE_PRINTF
#define USE_PRINTF      (1)
#endif

#include <string.h>

#ifndef TLSF_USE_LOCKS
#define TLSF_USE_LOCKS  (0)
#endif

#ifndef TLSF_STATISTIC
#define TLSF_STATISTIC  (0)
#endif

#ifndef USE_MMAP
#define USE_MMAP    (0)
#endif

#ifndef USE_SBRK
#define USE_SBRK    (0)
#endif

#if TLSF_USE_LOCKS
#include "target.h"
#else
#define TLSF_CREATE_LOCK(_unused_)   do{}while(0)
#define TLSF_DESTROY_LOCK(_unused_)  do{}while(0)
#define TLSF_ACQUIRE_LOCK(_unused_)  do{}while(0)
#define TLSF_RELEASE_LOCK(_unused_)  do{}while(0)
#endif

#if TLSF_STATISTIC
#define TLSF_ADD_SIZE(tlsf, b) do {                                 \
        tlsf->used_size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;  \
        if (tlsf->used_size > tlsf->max_size)                       \
            tlsf->max_size = tlsf->used_size;                       \
        } while(0)

#define TLSF_REMOVE_SIZE(tlsf, b) do {                              \
        tlsf->used_size -= (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;  \
    } while(0)
#else
#define TLSF_ADD_SIZE(tlsf, b)       do{}while(0)
#define TLSF_REMOVE_SIZE(tlsf, b)    do{}while(0)
#endif

#ifndef _WIN32
#if USE_MMAP || USE_SBRK
#include <unistd.h>
#endif
#endif

#ifndef _WIN32
#if USE_MMAP
#include <sys/mman.h>
#endif
#endif

#include "tlsf.h"

#if !defined(__GNUC__)
#ifndef __inline__
#define __inline__
#endif
#endif

#ifdef USE_PRINTF
#include <stdio.h>
# define PRINT_MSG(fmt, args...) printf(fmt, ## args)
# define ERROR_MSG(fmt, args...) printf(fmt, ## args)
#else
# if !defined(PRINT_MSG)
#  define PRINT_MSG(fmt, args...)
# endif
# if !defined(ERROR_MSG)
#  define ERROR_MSG(fmt, args...)
# endif
#endif

/* The  debug functions  only can  be used  when _DEBUG_TLSF_  is set. */
#ifndef _DEBUG_TLSF_
#define _DEBUG_TLSF_  (0)
#endif

#if defined(_WIN32)
#include "mman.h"
#endif

/*************************************************************************/
/* Definition of the structures used by TLSF */

/* Some IMPORTANT TLSF parameters */
/* Unlike the preview TLSF versions, now they are statics */
#define BLOCK_ALIGN (sizeof(void *) * 2)

#define MAX_FLI     (30)
#define MAX_LOG2_SLI    (5)
#define MAX_SLI     (1 << MAX_LOG2_SLI)     /* MAX_SLI = 2^MAX_LOG2_SLI */

#define FLI_OFFSET  (6)     /* tlsf structure just will manage blocks bigger */
/* than 128 bytes */
#define SMALL_BLOCK (128)
#define REAL_FLI    (MAX_FLI - FLI_OFFSET)
#define MIN_BLOCK_SIZE  (sizeof (free_ptr_t))
#define BHDR_OVERHEAD   (sizeof (bhdr_t) - MIN_BLOCK_SIZE)
#define TLSF_SIGNATURE  (0x2A59FA59)

#define PTR_MASK    (sizeof(void *) - 1)
#define BLOCK_SIZE  (0xFFFFFFFF - PTR_MASK)

#define GET_NEXT_BLOCK(_addr, _r) ((bhdr_t *) ((char *) (_addr) + (_r)))
#define MEM_ALIGN         ((BLOCK_ALIGN) - 1)
#define ROUNDUP_SIZE(_r)          (((_r) + MEM_ALIGN) & ~MEM_ALIGN)
#define ROUNDDOWN_SIZE(_r)        ((_r) & ~MEM_ALIGN)
#define ROUNDUP(_x, _v)           ((((~(_x)) + 1) & ((_v)-1)) + (_x))

#define BLOCK_STATE (0x1)
#define PREV_STATE  (0x2)

/* bit 0 of the block size */
#define FREE_BLOCK  (0x1)
#define USED_BLOCK  (0x0)

/* bit 1 of the block size */
#define PREV_FREE   (0x2)
#define PREV_USED   (0x0)

#define DEFAULT_AREA_SIZE (1024*10)

#ifdef USE_MMAP
#define PAGE_SIZE (getpagesize())
#endif

typedef unsigned int u32_t;     /* NOTE: Make sure that this type is 4 bytes long on your computer */
typedef unsigned char u8_t;     /* NOTE: Make sure that this type is 1 byte on your computer */

typedef struct free_ptr_struct {
    struct bhdr_struct *prev;
    struct bhdr_struct *next;
} free_ptr_t;

typedef struct bhdr_struct {
    /* This pointer is just valid if the first bit of size is set */
    struct bhdr_struct *prev_hdr;
    /* The size is stored in bytes */
    size_t size;                /* bit 0 indicates whether the block is used and */
    /* bit 1 allows to know whether the previous block is free */
    union {
        struct free_ptr_struct free_ptr;
        u8_t buffer[1];         /*sizeof(struct free_ptr_struct)]; */
    } ptr;
} bhdr_t;

/* This structure is embedded at the beginning of each area, giving us
 * enough information to cope with a set of areas */

typedef struct area_info_struct {
    bhdr_t *end;
    struct area_info_struct *next;
} area_info_t;

typedef struct TLSF_struct {
    /* the TLSF's structure signature */
    u32_t tlsf_signature;

#if TLSF_USE_LOCKS
    TLSF_MLOCK_T lock;
#endif

#if TLSF_STATISTIC
    /* These can not be calculated outside tlsf because we
     * do not know the sizes when freeing/reallocing memory. */
    size_t used_size;
    size_t max_size;
#endif

    /* A linked list holding all the existing areas */
    area_info_t *area_head;

    /* the first-level bitmap */
    /* This array should have a size of REAL_FLI bits */
    u32_t fl_bitmap;

    /* the second-level bitmap */
    u32_t sl_bitmap[REAL_FLI];

    bhdr_t *matrix[REAL_FLI][MAX_SLI];
} tlsf_t;

/******************************************************************/
/**************     Helping functions    **************************/
/******************************************************************/
static __inline__ void set_bit(int nr, u32_t * addr);
static __inline__ void clear_bit(int nr, u32_t * addr);
static __inline__ int ls_bit(int x);
static __inline__ int ms_bit(int x);
static __inline__ void MAPPING_SEARCH(size_t * _r, int *_fl, int *_sl);
static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl);
static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl);
static __inline__ bhdr_t *process_area(void *area, size_t size);
#if USE_SBRK || USE_MMAP
static __inline__ void *get_new_area(size_t * size);
#endif

static const int table[] = {
    -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
    4, 4,
    4, 4, 4, 4, 4, 4, 4,
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
    5,
    5, 5, 5, 5, 5, 5, 5,
    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
    6,
    6, 6, 6, 6, 6, 6, 6,
    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
    6,
    6, 6, 6, 6, 6, 6, 6,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
    7,
    7, 7, 7, 7, 7, 7, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
    7,
    7, 7, 7, 7, 7, 7, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
    7,
    7, 7, 7, 7, 7, 7, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
    7,
    7, 7, 7, 7, 7, 7, 7
};

static __inline__ int ls_bit(int i)
{
    unsigned int a;
    unsigned int x = i & -i;

    a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
    return table[x >> a] + a;
}

static __inline__ int ms_bit(int i)
{
    unsigned int a;
    unsigned int x = (unsigned int) i;

    a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
    return table[x >> a] + a;
}

static __inline__ void set_bit(int nr, u32_t * addr)
{
    addr[nr >> 5] |= 1 << (nr & 0x1f);
}

static __inline__ void clear_bit(int nr, u32_t * addr)
{
    addr[nr >> 5] &= ~(1 << (nr & 0x1f));
}

static __inline__ void MAPPING_SEARCH(size_t * _r, int *_fl, int *_sl)
{
    int _t;

    if (*_r < SMALL_BLOCK) {
        *_fl = 0;
        *_sl = *_r / (SMALL_BLOCK / MAX_SLI);
    } else {
        _t = (1 << (ms_bit(*_r) - MAX_LOG2_SLI)) - 1;
        *_r = *_r + _t;
        *_fl = ms_bit(*_r);
        *_sl = (*_r >> (*_fl - MAX_LOG2_SLI)) - MAX_SLI;
        *_fl -= FLI_OFFSET;
        /*if ((*_fl -= FLI_OFFSET) < 0) // FL wil be always >0!
         *_fl = *_sl = 0;
         */
        *_r &= ~_t;
    }
}

static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl)
{
    if (_r < SMALL_BLOCK) {
        *_fl = 0;
        *_sl = _r / (SMALL_BLOCK / MAX_SLI);
    } else {
        *_fl = ms_bit(_r);
        *_sl = (_r >> (*_fl - MAX_LOG2_SLI)) - MAX_SLI;
        *_fl -= FLI_OFFSET;
    }
}

static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl)
{
    u32_t _tmp = _tlsf->sl_bitmap[*_fl] & (~0 << *_sl);
    bhdr_t *_b = NULL;

    if (_tmp) {
        *_sl = ls_bit(_tmp);
        _b = _tlsf->matrix[*_fl][*_sl];
    } else {
        *_fl = ls_bit(_tlsf->fl_bitmap & (~0 << (*_fl + 1)));
        if (*_fl > 0) {         /* likely */
            *_sl = ls_bit(_tlsf->sl_bitmap[*_fl]);
            _b = _tlsf->matrix[*_fl][*_sl];
        }
    }
    return _b;
}

#define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl) do {                 \
        _tlsf -> matrix [_fl] [_sl] = _b -> ptr.free_ptr.next;      \
        if (_tlsf -> matrix[_fl][_sl])                              \
            _tlsf -> matrix[_fl][_sl] -> ptr.free_ptr.prev = NULL;  \
        else {                                                      \
            clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]);             \
            if (!_tlsf -> sl_bitmap [_fl])                          \
                clear_bit (_fl, &_tlsf -> fl_bitmap);               \
        }                                                           \
        _b -> ptr.free_ptr.prev =  NULL;                \
        _b -> ptr.free_ptr.next =  NULL;                \
    }while(0)

#define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl) do {                         \
        if (_b -> ptr.free_ptr.next)                                    \
            _b -> ptr.free_ptr.next -> ptr.free_ptr.prev = _b -> ptr.free_ptr.prev; \
        if (_b -> ptr.free_ptr.prev)                                    \
            _b -> ptr.free_ptr.prev -> ptr.free_ptr.next = _b -> ptr.free_ptr.next; \
        if (_tlsf -> matrix [_fl][_sl] == _b) {                         \
            _tlsf -> matrix [_fl][_sl] = _b -> ptr.free_ptr.next;       \
            if (!_tlsf -> matrix [_fl][_sl]) {                          \
                clear_bit (_sl, &_tlsf -> sl_bitmap[_fl]);              \
                if (!_tlsf -> sl_bitmap [_fl])                          \
                    clear_bit (_fl, &_tlsf -> fl_bitmap);               \
            }                                                           \
        }                                                               \
        _b -> ptr.free_ptr.prev = NULL;                 \
        _b -> ptr.free_ptr.next = NULL;                 \
    } while(0)

#define INSERT_BLOCK(_b, _tlsf, _fl, _sl) do {                          \
        _b -> ptr.free_ptr.prev = NULL; \
        _b -> ptr.free_ptr.next = _tlsf -> matrix [_fl][_sl]; \
        if (_tlsf -> matrix [_fl][_sl])                                 \
            _tlsf -> matrix [_fl][_sl] -> ptr.free_ptr.prev = _b;       \
        _tlsf -> matrix [_fl][_sl] = _b;                                \
        set_bit (_sl, &_tlsf -> sl_bitmap [_fl]);                       \
        set_bit (_fl, &_tlsf -> fl_bitmap);                             \
    } while(0)

#if USE_SBRK || USE_MMAP
static __inline__ void *get_new_area(size_t * size)
{
    void *area;

#if USE_SBRK
    area = (void *)sbrk(0);
    if (((void *)sbrk(*size)) != ((void *) -1))
        return area;
#endif

/* The NT emulation of mmap as supplied here treats all mmap(2) as anonymous */
#if !defined(MAP_ANONYMOUS) && !defined(_WIN32)
/* https://dev.openwrt.org/ticket/322 */
# define MAP_ANONYMOUS MAP_ANON
#endif

#if USE_MMAP
    *size = ROUNDUP(*size, PAGE_SIZE);
#ifndef _WIN32
    if ((area = mmap(0, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED)
#else
    if ((area = mmap(0, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE, -1, 0)) != MAP_FAILED)
#endif
        return area;
#endif
    return ((void *) ~0);
}
#endif

static __inline__ bhdr_t *process_area(void *area, size_t size)
{
    bhdr_t *b, *lb, *ib;
    area_info_t *ai;

    ib = (bhdr_t *) area;
    ib->size =
        (sizeof(area_info_t) <
         MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(sizeof(area_info_t)) | USED_BLOCK | PREV_USED;
    b = (bhdr_t *) GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE);
    b->size = ROUNDDOWN_SIZE(size - 3 * BHDR_OVERHEAD - (ib->size & BLOCK_SIZE)) | USED_BLOCK | PREV_USED;
    b->ptr.free_ptr.prev = b->ptr.free_ptr.next = 0;
    lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
    lb->prev_hdr = b;
    lb->size = 0 | USED_BLOCK | PREV_FREE;
    ai = (area_info_t *) ib->ptr.buffer;
    ai->next = 0;
    ai->end = lb;
    return ib;
}

/******************************************************************/
/******************** Begin of the allocator code *****************/
/******************************************************************/

static char *mp = NULL;         /* Default memory pool. */

/******************************************************************/
size_t init_memory_pool(size_t mem_pool_size, void *mem_pool)
{
/* This initialises the stack-allocation mode of 2LSF, you must
   declare your own fixed-size blocks beforehand, somewhere in the
   data segment of your app.
*/
/******************************************************************/
    tlsf_t *tlsf;
    bhdr_t *b, *ib;

    if (!mem_pool || !mem_pool_size || mem_pool_size < sizeof(tlsf_t) + BHDR_OVERHEAD * 8) {
        ERROR_MSG("init_memory_pool (): memory_pool invalid\n");
        return -1;
    }

    if (((unsigned long) mem_pool & PTR_MASK)) {
        ERROR_MSG("init_memory_pool (): mem_pool must be aligned to a word\n");
        return -1;
    }
    tlsf = (tlsf_t *) mem_pool;
    /* Check if already initialised */
    if (tlsf->tlsf_signature == TLSF_SIGNATURE) {
        mp = mem_pool;
        b = GET_NEXT_BLOCK(mp, ROUNDUP_SIZE(sizeof(tlsf_t)));
        return b->size & BLOCK_SIZE;
    }

    mp = mem_pool;

    /* Zeroing the memory pool */
    memset(mem_pool, 0, sizeof(tlsf_t));

    tlsf->tlsf_signature = TLSF_SIGNATURE;

    TLSF_CREATE_LOCK(&tlsf->lock);

    ib = process_area(GET_NEXT_BLOCK
                      (mem_pool, ROUNDUP_SIZE(sizeof(tlsf_t))), ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t)));
    b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE);
    free_ex(b->ptr.buffer, tlsf);
    tlsf->area_head = (area_info_t *) ib->ptr.buffer;

#if TLSF_STATISTIC
    tlsf->used_size = mem_pool_size - (b->size & BLOCK_SIZE);
    tlsf->max_size = tlsf->used_size;
#endif

    return (b->size & BLOCK_SIZE);
}

/******************************************************************/
size_t add_new_area(void *area, size_t area_size, void *mem_pool)
{
/******************************************************************/
    tlsf_t *tlsf = (tlsf_t *) mem_pool;
    area_info_t *ptr, *ptr_prev, *ai;
    bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b;

    memset(area, 0, area_size);
    ptr = tlsf->area_head;
    ptr_prev = 0;

    ib0 = process_area(area, area_size);
    b0 = GET_NEXT_BLOCK(ib0->ptr.buffer, ib0->size & BLOCK_SIZE);
    lb0 = GET_NEXT_BLOCK(b0->ptr.buffer, b0->size & BLOCK_SIZE);

    /* Before inserting the new area, we have to merge this area with the
       already existing ones */

    while (ptr) {
        ib1 = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
        b1 = GET_NEXT_BLOCK(ib1->ptr.buffer, ib1->size & BLOCK_SIZE);
        lb1 = ptr->end;

        /* Merging the new area with the next physically contigous one */
        if ((unsigned long) ib1 == (unsigned long) lb0 + BHDR_OVERHEAD) {
            if (tlsf->area_head == ptr) {
                tlsf->area_head = ptr->next;
                ptr = ptr->next;
            } else {
                ptr_prev->next = ptr->next;
                ptr = ptr->next;
            }

            b0->size =
                ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) +
                               (ib1->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | PREV_USED;

            b1->prev_hdr = b0;
            lb0 = lb1;

            continue;
        }

        /* Merging the new area with the previous physically contigous
           one */
        if ((unsigned long) lb1->ptr.buffer == (unsigned long) ib0) {
            if (tlsf->area_head == ptr) {
                tlsf->area_head = ptr->next;
                ptr = ptr->next;
            } else {
                ptr_prev->next = ptr->next;
                ptr = ptr->next;
            }

            lb1->size =
                ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) +
                               (ib0->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | (lb1->size & PREV_STATE);
            next_b = GET_NEXT_BLOCK(lb1->ptr.buffer, lb1->size & BLOCK_SIZE);
            next_b->prev_hdr = lb1;
            b0 = lb1;
            ib0 = ib1;

            continue;
        }
        ptr_prev = ptr;
        ptr = ptr->next;
    }

    /* Inserting the area in the list of linked areas */
    ai = (area_info_t *) ib0->ptr.buffer;
    ai->next = tlsf->area_head;
    ai->end = lb0;
    tlsf->area_head = ai;
    free_ex(b0->ptr.buffer, mem_pool);
    return (b0->size & BLOCK_SIZE);
}

/******************************************************************/
size_t get_used_size(void *mem_pool)
{
/******************************************************************/
#if TLSF_STATISTIC
    return ((tlsf_t *) mem_pool)->used_size;
#else
    return 0;
#endif
}

/******************************************************************/
size_t get_max_size(void *mem_pool)
{
/******************************************************************/
#if TLSF_STATISTIC
    return ((tlsf_t *) mem_pool)->max_size;
#else
    return 0;
#endif
}

/******************************************************************/
void destroy_memory_pool(void *mem_pool)
{
/******************************************************************/
    tlsf_t *tlsf = (tlsf_t *) mem_pool;

    tlsf->tlsf_signature = 0;

    TLSF_DESTROY_LOCK(&tlsf->lock);

}

/******************************************************************/
void *tlsf_malloc(size_t size)
{
/******************************************************************/
    void *ret;

#if USE_MMAP || USE_SBRK // Dynamic allocation using POSIX facilities (must port if undefined)
    if (!mp) {
        size_t area_size;
        void *area;

        area_size = sizeof(tlsf_t) + BHDR_OVERHEAD * 8; /* Just a safety constant */
        area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE;
        area = get_new_area(&area_size);
        if (area == ((void *) ~0))
            return NULL;        /* Not enough system memory */
        init_memory_pool(area_size, area);
    }
#endif

    // Dynamic allocation using stack/fixed-block pool
    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);

    ret = malloc_ex(size, mp);

    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);

    return ret;
}

/******************************************************************/
void tlsf_free(void *ptr)
{
/******************************************************************/

    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);

    free_ex(ptr, mp);

    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);

}

/******************************************************************/
void *tlsf_realloc(void *ptr, size_t size)
{
/******************************************************************/
    void *ret;

#if USE_MMAP || USE_SBRK
    if (!mp) {
        return tlsf_malloc(size);
    }
#endif

    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);

    ret = realloc_ex(ptr, size, mp);

    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);

    return ret;
}

/******************************************************************/
void *tlsf_calloc(size_t nelem, size_t elem_size)
{
/******************************************************************/
    void *ret;

    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);

    ret = calloc_ex(nelem, elem_size, mp);

    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);

    return ret;
}

/******************************************************************/
void *malloc_ex(size_t size, void *mem_pool)
{
/******************************************************************/
    tlsf_t *tlsf = (tlsf_t *) mem_pool;
    bhdr_t *b, *b2, *next_b;
    int fl, sl;
    size_t tmp_size;

    size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size);

    /* Rounding up the requested size and calculating fl and sl */
    MAPPING_SEARCH(&size, &fl, &sl);

    /* Searching a free block, recall that this function changes the values of fl and sl,
       so they are not longer valid when the function fails */
    b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
#if USE_MMAP || USE_SBRK
    if (!b) {
        size_t area_size;
        void *area;
        /* Growing the pool size when needed */
        area_size = size + BHDR_OVERHEAD * 8;   /* size plus enough room for the requered headers. */
        area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE;
        area = get_new_area(&area_size);        /* Call sbrk or mmap */
        if (area == ((void *) ~0))
            return NULL;        /* Not enough system memory */
        add_new_area(area, area_size, mem_pool);
        /* Rounding up the requested size and calculating fl and sl */
        MAPPING_SEARCH(&size, &fl, &sl);
        /* Searching a free block */
        b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
    }
#endif
    if (!b)
        return NULL;            /* Not found */

    EXTRACT_BLOCK_HDR(b, tlsf, fl, sl);

    /*-- found: */
    next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
    /* Should the block be split? */
    tmp_size = (b->size & BLOCK_SIZE) - size;
    if (tmp_size >= sizeof(bhdr_t)) {
        tmp_size -= BHDR_OVERHEAD;
        b2 = GET_NEXT_BLOCK(b->ptr.buffer, size);
        b2->size = tmp_size | FREE_BLOCK | PREV_USED;
        next_b->prev_hdr = b2;
        MAPPING_INSERT(tmp_size, &fl, &sl);
        INSERT_BLOCK(b2, tlsf, fl, sl);

        b->size = size | (b->size & PREV_STATE);
    } else {
        next_b->size &= (~PREV_FREE);
        b->size &= (~FREE_BLOCK);       /* Now it's used */
    }

    TLSF_ADD_SIZE(tlsf, b);

    return (void *) b->ptr.buffer;
}

/******************************************************************/
void free_ex(void *ptr, void *mem_pool)
{
/******************************************************************/
    tlsf_t *tlsf = (tlsf_t *) mem_pool;
    bhdr_t *b, *tmp_b;
    int fl = 0, sl = 0;

    if (!ptr) {
        return;
    }
    b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
    b->size |= FREE_BLOCK;

    TLSF_REMOVE_SIZE(tlsf, b);

    b->ptr.free_ptr.prev = NULL;
    b->ptr.free_ptr.next = NULL;
    tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
    if (tmp_b->size & FREE_BLOCK) {
        MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl);
        EXTRACT_BLOCK(tmp_b, tlsf, fl, sl);
        b->size += (tmp_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
    }
    if (b->size & PREV_FREE) {
        tmp_b = b->prev_hdr;
        MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl);
        EXTRACT_BLOCK(tmp_b, tlsf, fl, sl);
        tmp_b->size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
        b = tmp_b;
    }
    MAPPING_INSERT(b->size & BLOCK_SIZE, &fl, &sl);
    INSERT_BLOCK(b, tlsf, fl, sl);

    tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
    tmp_b->size |= PREV_FREE;
    tmp_b->prev_hdr = b;
}

/******************************************************************/
void *realloc_ex(void *ptr, size_t new_size, void *mem_pool)
{
/******************************************************************/
    tlsf_t *tlsf = (tlsf_t *) mem_pool;
    void *ptr_aux;
    unsigned int cpsize;
    bhdr_t *b, *tmp_b, *next_b;
    int fl, sl;
    size_t tmp_size;

    if (!ptr) {
        if (new_size)
            return (void *) malloc_ex(new_size, mem_pool);
        if (!new_size)
            return NULL;
    } else if (!new_size) {
        free_ex(ptr, mem_pool);
        return NULL;
    }

    b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
    next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
    new_size = (new_size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(new_size);
    tmp_size = (b->size & BLOCK_SIZE);
    if (new_size <= tmp_size) {
    TLSF_REMOVE_SIZE(tlsf, b);
        if (next_b->size & FREE_BLOCK) {
            MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl);
            EXTRACT_BLOCK(next_b, tlsf, fl, sl);
            tmp_size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
            next_b = GET_NEXT_BLOCK(next_b->ptr.buffer, next_b->size & BLOCK_SIZE);
            /* We allways reenter this free block because tmp_size will
               be greater then sizeof (bhdr_t) */
        }
        tmp_size -= new_size;
        if (tmp_size >= sizeof(bhdr_t)) {
            tmp_size -= BHDR_OVERHEAD;
            tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size);
            tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED;
            next_b->prev_hdr = tmp_b;
            next_b->size |= PREV_FREE;
            MAPPING_INSERT(tmp_size, &fl, &sl);
            INSERT_BLOCK(tmp_b, tlsf, fl, sl);
            b->size = new_size | (b->size & PREV_STATE);
        }
    TLSF_ADD_SIZE(tlsf, b);
        return (void *) b->ptr.buffer;
    }
    if ((next_b->size & FREE_BLOCK)) {
        if (new_size <= (tmp_size + (next_b->size & BLOCK_SIZE))) {
            TLSF_REMOVE_SIZE(tlsf, b);
            MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl);
            EXTRACT_BLOCK(next_b, tlsf, fl, sl);
            b->size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
            next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
            next_b->prev_hdr = b;
            next_b->size &= ~PREV_FREE;
            tmp_size = (b->size & BLOCK_SIZE) - new_size;
            if (tmp_size >= sizeof(bhdr_t)) {
                tmp_size -= BHDR_OVERHEAD;
                tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size);
                tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED;
                next_b->prev_hdr = tmp_b;
                next_b->size |= PREV_FREE;
                MAPPING_INSERT(tmp_size, &fl, &sl);
                INSERT_BLOCK(tmp_b, tlsf, fl, sl);
                b->size = new_size | (b->size & PREV_STATE);
            }
            TLSF_ADD_SIZE(tlsf, b);
            return (void *) b->ptr.buffer;
        }
    }

    if (!(ptr_aux = malloc_ex(new_size, mem_pool))){
        return NULL;
    }

    cpsize = ((b->size & BLOCK_SIZE) > new_size) ? new_size : (b->size & BLOCK_SIZE);

    memcpy(ptr_aux, ptr, cpsize);

    free_ex(ptr, mem_pool);
    return ptr_aux;
}

/******************************************************************/
void *calloc_ex(size_t nelem, size_t elem_size, void *mem_pool)
{
/******************************************************************/
    void *ptr;

    if (nelem <= 0 || elem_size <= 0)
        return NULL;

    if (!(ptr = malloc_ex(nelem * elem_size, mem_pool)))
        return NULL;
    memset(ptr, 0, nelem * elem_size);

    return ptr;
}

#if _DEBUG_TLSF_

/***************  DEBUG FUNCTIONS   **************/

/* The following functions have been designed to ease the debugging of */
/* the TLSF  structure.  For non-developing  purposes, it may  be they */
/* haven't too much worth.  To enable them, _DEBUG_TLSF_ must be set.  */

extern void dump_memory_region(unsigned char *mem_ptr, unsigned int size);
extern void print_block(bhdr_t * b);
extern void print_tlsf(tlsf_t * tlsf);
void print_all_blocks(tlsf_t * tlsf);

void dump_memory_region(unsigned char *mem_ptr, unsigned int size)
{

    unsigned long begin = (unsigned long) mem_ptr;
    unsigned long end = (unsigned long) mem_ptr + size;
    int column = 0;

    begin >>= 2;
    begin <<= 2;

    end >>= 2;
    end++;
    end <<= 2;

    PRINT_MSG("\nMemory region dumped: 0x%lx - 0x%lx\n\n", begin, end);

    column = 0;
    PRINT_MSG("0x%lx ", begin);

    while (begin < end) {
        if (((unsigned char *) begin)[0] == 0)
            PRINT_MSG("00");
        else
            PRINT_MSG("%02x", ((unsigned char *) begin)[0]);
        if (((unsigned char *) begin)[1] == 0)
            PRINT_MSG("00 ");
        else
            PRINT_MSG("%02x ", ((unsigned char *) begin)[1]);
        begin += 2;
        column++;
        if (column == 8) {
            PRINT_MSG("\n0x%lx ", begin);
            column = 0;
        }

    }
    PRINT_MSG("\n\n");
}

void print_block(bhdr_t * b)
{
    if (!b)
        return;
    PRINT_MSG(">> [%p] (", b);
    if ((b->size & BLOCK_SIZE))
        PRINT_MSG("%lu bytes, ", (unsigned long) (b->size & BLOCK_SIZE));
    else
        PRINT_MSG("sentinel, ");
    if ((b->size & BLOCK_STATE) == FREE_BLOCK)
        PRINT_MSG("free [%p, %p], ", b->ptr.free_ptr.prev, b->ptr.free_ptr.next);
    else
        PRINT_MSG("used, ");
    if ((b->size & PREV_STATE) == PREV_FREE)
        PRINT_MSG("prev. free [%p])\n", b->prev_hdr);
    else
        PRINT_MSG("prev used)\n");
}

void print_tlsf(tlsf_t * tlsf)
{
    bhdr_t *next;
    int i, j;

    PRINT_MSG("\nTLSF at %p\n", tlsf);

    PRINT_MSG("FL bitmap: 0x%x\n\n", (unsigned) tlsf->fl_bitmap);

    for (i = 0; i < REAL_FLI; i++) {
        if (tlsf->sl_bitmap[i])
            PRINT_MSG("SL bitmap 0x%x\n", (unsigned) tlsf->sl_bitmap[i]);
        for (j = 0; j < MAX_SLI; j++) {
            next = tlsf->matrix[i][j];
            if (next)
                PRINT_MSG("-> [%d][%d]\n", i, j);
            while (next) {
                print_block(next);
                next = next->ptr.free_ptr.next;
            }
        }
    }
}

void print_all_blocks(tlsf_t * tlsf)
{
    area_info_t *ai;
    bhdr_t *next;
    PRINT_MSG("\nTLSF at %p\nALL BLOCKS\n\n", tlsf);
    ai = tlsf->area_head;
    while (ai) {
        next = (bhdr_t *) ((char *) ai - BHDR_OVERHEAD);
        while (next) {
            print_block(next);
            if ((next->size & BLOCK_SIZE))
                next = GET_NEXT_BLOCK(next->ptr.buffer, next->size & BLOCK_SIZE);
            else
                next = NULL;
        }
        ai = ai->next;
    }
}

#endif
#ifdef __cplusplus
}
#endif


code:
/*
 * Two Levels Segregate Fit memory allocator (TLSF)
 * Version 2.4.6
 *
 * Written by Miguel Masmano Tello <mimastel@doctor.upv.es>
 *
 * Thanks to Ismael Ripoll for his suggestions and reviews
 *
 * Copyright (C) 2008, 2007, 2006, 2005, 2004
 *
 * This code is released using a dual license strategy: GPL/LGPL
 * You can choose the licence that better fits your requirements.
 *
 * Released under the terms of the GNU General Public License Version 2.0
 * Released under the terms of the GNU Lesser General Public License Version 2.1
 *
 */

#ifndef _TLSF_H_
#define _TLSF_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>

extern size_t init_memory_pool(size_t, void *);
extern size_t get_used_size(void *);
extern size_t get_max_size(void *);
extern void destroy_memory_pool(void *);
extern size_t add_new_area(void *, size_t, void *);
extern void *malloc_ex(size_t, void *);
extern void free_ex(void *, void *);
extern void *realloc_ex(void *, size_t, void *);
extern void *calloc_ex(size_t, size_t, void *);

extern void *tlsf_malloc(size_t size);
extern void tlsf_free(void *ptr);
extern void *tlsf_realloc(void *ptr, size_t size);
extern void *tlsf_calloc(size_t nelem, size_t elem_size);

#ifdef __cplusplus
}
#endif
#endif


code:
#include "BrowsingHistory.h"

BrowsingHistory::BrowsingHistory(std::function<void(URL const&)> onGotoPage_) :
    history(),
    currentPosition(history.end()),
    onGotoPage(onGotoPage_) {}

size_t BrowsingHistory::length() const {
    return history.size();
}

void BrowsingHistory::back() {
    go(-1);
}

void BrowsingHistory::forward() {
    go(1);
}

void BrowsingHistory::go() {
    go(0);
}

void BrowsingHistory::go(int diff) {
    if (history.size() == 0) {
        return;
    }
    std::vector<URL>::iterator newPos = currentPosition + diff;
    if (newPos >= history.begin() && newPos < history.end()) {
        currentPosition = newPos;
        onGotoPage(*currentPosition);
    }
}

void BrowsingHistory::pushState(void* stateObj, std::string const& title, URL const& url) {
    if (history.size() == 0) {
        history.push_back(url);
        currentPosition = history.begin();
        return;
    }
    URL currentURL = *currentPosition;
    history.erase(++currentPosition, history.end());
    history.push_back(currentURL.merge(url));
    currentPosition = history.end() - 1;
}

void BrowsingHistory::replaceState(void* stateObj, std::string const& title, URL const& url) {
    if (history.size() == 0) {
        return;
    }
    *currentPosition = (*currentPosition).merge(url);
}

void BrowsingHistory::print() {
    int i = 0;
    for(std::vector<URL>::iterator it=history.begin(); it!=history.end(); ++it) {
        std::cout << "BrowsingHistory::print " << i << ": " << it->toString() << std::endl;
        i++;
    }
}


code:
#ifndef BROWSINGHISTORY_H
#define BROWSINGHISTORY_H

#include <vector>
#include "URL.h"
#include <functional>

struct pointInHistory {
    URL realURL;
    URL displayURL;
    std::string title;
    void* stateObj; // limit of 640k here
};

/*
  NOTE: The first parameter of the constructor is the callback to be called when
        calling go(int) (or back or forward or whatever). Should be a
        function that navigates to the specified URL.
 */

// modelled after https://developer.mozilla.org/en-US/docs/Web/API/History
class BrowsingHistory {
public:
    BrowsingHistory(std::function<void(URL const&)> onGotoPage_);

    size_t length() const;
    //void scrollRestoration(); // TODO: Implement this when it's relevant
    //void* state() const; // TODO: Implement when we have Javascript objects.

    void back();
    void forward();
    void go();
    void go(int diff);

    // stateObj: void* should be a Javascript object once we have those. Just
    //           give it nullptr for the time being.
    // title: "Firefox currently ignores this parameter, although it may
    //         use it in the future.". So i guess we ignore it too? well we'll make plans to properly use it.
    void pushState(void* stateObj, std::string const& title, URL const& url);
    void replaceState(void* stateObj, std::string const& title, URL const& url);
    // onGotoPage can call onPopState... or maybe it should be renamed?
    // onPopState <- call when fwd/bck are used and sends the state associated with that point in history
    void print();

private:
    // push overrides the real URL with a display URL, we'll need to store both
    // also need to store a state
    std::vector<URL> history;
    std::vector<URL>::iterator currentPosition;
    std::function<void(URL const&)> onGotoPage;
};

#endif


code:
// ©2008-2017 despair <despair@netrunner.cc>
#include "CFGFileParser.h"
#include <climits>
#include "../platform/slre.h"

CFGFileParser::CFGFileParser(const char* filename){
    // Open the config file, get its size,
    // allocate the buffer, read it into
    // the buffer, close the file
    cfg_file = fopen(filename, "rb"); // On NT, opening in text mode translates \n into \r\n
    stat(filename, cfg_fileinfo);
    buffer = static_cast<char*>(tlsf_malloc(cfg_fileinfo->st_size & INT_MAX));
    if (cfg_file) {
        bytesRead = fread(buffer, sizeof(char) & INT_MAX, cfg_fileinfo->st_size & INT_MAX, cfg_file);
        if (!bytesRead) {
            std::cout << "can't read config" << std::endl;
        }
    } else {
        std::cout << "can't open config" << std::endl;
    }
    fclose(cfg_file);
}

CFGFileParser::CFGFileParser(ntr::fast_string in_buf){
    buffer = static_cast<char*>(tlsf_malloc(strlen(in_buf.c_str()) & INT_MAX));
    strcpy(buffer, in_buf.c_str());
}

CFGFileParser::~CFGFileParser(){
    // clean up!
    // This buffer has been written to and co-opted by
    // libc itself, but it stands that we initially allocated
    // it. So we'll free it ourselves.
    tlsf_free(buffer);
    // We've already copied the collected config directives
    // into a global class, we can safely delete the scratch
    // object, and its file info block.
    tlsf_free(cfg_fileinfo);
    delete cfg;
}

bool CFGFileParser::ParseText() {
    // Initial buffer for pass 1. tmp holds the config file (fmr. buffer)
    // token holds the actual token. pass1_length to keep track of memory,
    // reallocate as needed.
    char *tmp, *token;
    size_t pass1_length = 0;
    struct slre regex; // final validation before adding to second-pass buffer
    // Second pass. All comments and .tags stripped out. Starts off at 512 bytes, increases if necessary.
    char* directives = static_cast<char*>(tlsf_malloc(512));
    char* tmp2;
    token = strtok_r(buffer, "\n", &tmp);
    while (token != nullptr) {
        if (token[0] == '#' || token[0] == '.' || token[0] == '\n'){ // Comment, Perl directive, or single <LF> found, skip over
            token = strtok_r(nullptr, "\n", &tmp);
        }
        else if (!isalpha(token[0])){ // The leading character is NOT a #, ., <LF>, or a letter. NB: Leading numbers are also invalid.
            printf("ERROR: Config file is invalid: ");
            printf("\"%s\"\n",token);
            return false;
        }
        else {
            // FIXME: brackets are not always required!
            if (!slre_compile(&regex, "([A-Z0-9_]*)(:)(\\[.*\\])")){
                printf("Internal error.\n");
                return false;
            }
            if (!slre_match(&regex, token, strlen(token), nullptr)){
                printf("Invalid directive: \"%s\"\n", token); // regex matches DiReC[_]T[I1]VE:[token], it simply cannot start with a number or symbol.
                return false;
            }
            // Config directive found, add to second-pass buffer
            // once we reach the 0.5KB mark, realloc exactly enough to keep going
            if (pass1_length >= 512){
                tlsf_realloc(directives, pass1_length+strlen(token)+2);
            }
            strcat(directives, token);
            strcat(directives, "\t");
            pass1_length = strlen(directives);
            token = strtok_r(nullptr, "\n", &tmp); // continue
        }
    }
    // First pass complete, second pass: break up into single directives and <key, value> pairs
    char *newScope;
    token = strtok_r(directives, "\t", &newScope);
    ntr::fast_string key, value;
    while (token != nullptr){
        key=strtok_r(token, ":", &tmp2);
        value=strtok_r(nullptr, "[]", &tmp2);
        // strip ending bracket
        cfg->Settings.insert({key,value});
        token = strtok_r(nullptr, "\t", &newScope);
    }
    #ifdef DEBUG
    std::cout << "Settings stringmap contains, in no particular order:\n";
    for ( auto it = cfg->Settings.begin(); it != cfg->Settings.end(); ++it ){
        std::cout << it->first << ":" << it->second << std::endl;
    }
    std::cout << std::endl;
    #endif
    // clean up, we're done parsing
    tlsf_free(directives);
    return true;
}

// Writes the fully parsed configuration to a BrowserConfiguration
// object supplied by the user.
void CFGFileParser::WriteConfig(BrowserConfiguration &config){
    config.Settings = cfg->Settings;
}


code:
// ©2008-2017 despair <despair@netrunner.cc>
#ifndef __CFGFILEPARSER_H__
#define __CFGFILEPARSER_H__
#include "../platform/netrunner.h"
#include <sys/stat.h>
#include <cstdint>

// Class which holds the parsed configuration options after
// being processed by CFGFileParser. No longer a "trivial class"
// just select by cfg->GlobalSettings....
struct BrowserConfiguration{
    ntr::stringmap Settings;
    // fast allocation!
    static void* operator new(std::size_t n){
         if (void *mem = tlsf_malloc(n)) {
             return mem;
         } throw std::bad_alloc {};
    }
    static void operator delete(void *p) {
        tlsf_free(p);
    }
    void clear();
};

class CFGFileParser {
public:
    // Opens config from external file.
    CFGFileParser(const char* filename);
    // Opens config from memory.
    CFGFileParser(ntr::fast_string in_buf);
    ~CFGFileParser();
    bool ParseText();
    void WriteConfig(BrowserConfiguration &config);
    static void* operator new(std::size_t n) {
        if (void *mem = tlsf_malloc(n)){
             return mem;
         } throw std::bad_alloc {};
    }
    static void operator delete(void *p) {
        tlsf_free(p);
    }
private:
    FILE *cfg_file;
    char *buffer;
    struct stat *cfg_fileinfo = reinterpret_cast<struct stat*>(tlsf_malloc(sizeof(struct stat)));
    BrowserConfiguration *cfg = new BrowserConfiguration();
    size_t bytesRead;
};
#endif // __CFGFILEPARSER_H__


code:
#include "CommandLineParams.h"

#include <vector>

namespace {
    std::vector<std::string> params;
}

void initCLParams(int argc, char *argv[]) {
    params = std::vector<std::string> (argv, argv + argc);
}

bool getCLParam(std::string const& param) {
    for (auto const& p : params) {
        if (p == param) {
            return true;
        }
    }
    return false;
}

std::string getCLParamByIndex(unsigned int i) {
    if (i < params.size()) {
        return params[i];
    }
    return "";
}

std::string getRelativeCLParam(std::string const& param, int i) {
    for (unsigned int index = 0; index < params.size(); ++index) {
        if (params[index] == param) {
            int si = static_cast<int>(index);
            unsigned int finalPos = static_cast<unsigned int>(si + i);
            if (finalPos < params.size()) {
                return params[finalPos];
            }
            return "";
        }
    }
    return "";
}


code:
#ifndef COMMANDLINEPARAMS_H
#define COMMANDLINEPARAMS_H

#include <string>

void initCLParams(int argc, char *argv[]);

// USAGE: getCLParam("-example")
bool getCLParam(std::string const& param);

// 0 is the program name
std::string getCLParamByIndex(unsigned int i);

// USAGE: getRelativeCLParam("-example", 1) gives the param after -example
std::string getRelativeCLParam(std::string const& param, int i);

#endif


code:
#include "FormData.h"

// how do we match up nodes to components to extract the current values out of the components?
// well we link input components back to node (and/or nodes back to components)
// or we create a form UI component
std::unique_ptr<std::map<std::string, std::string>> buildFormData(std::shared_ptr<Node> formNode, std::unique_ptr<std::map<std::string, std::string>> result) {
    if (!result) {
        result = std::make_unique<std::map<std::string, std::string>>();
    }
    // check this node
    TagNode *tagNode = dynamic_cast<TagNode*>(formNode.get());
    if (tagNode) {
        auto typePropIter = tagNode->properties.find("type");
        bool skip = false;
        std::cout << "formData.buildFormData - tagNode element " << tagNode->tag << std::endl;
        if (typePropIter != tagNode->properties.end()) {
            if (typePropIter->second == "submit") {
                skip = true;
            }
            if (typePropIter->second == "checkbox") {
                // FIXME: see if it's checked or not
                skip = true;
            }
            if (typePropIter->second == "radio") {
                // FIXME: see if it's checked or not
                skip = true;
            }
        }
        auto namePropIter = tagNode->properties.find("name");
        if (!skip && namePropIter != tagNode->properties.end()) {
            auto valuePropIter = tagNode->properties.find("value");
            if (valuePropIter != tagNode->properties.end()) {
                auto it = result->find(namePropIter->second);
                if (it == result->end()) {
                    std::cout << "INPUTElement.buildFormData - setting " << namePropIter->second << " to [" << valuePropIter->second << "]" << std::endl;
                    result->insert(std::pair<std::string, std::string>(namePropIter->second, valuePropIter->second));
                } else {
                    (*result)[namePropIter->second] = valuePropIter->second;
                }
            }
        }
    }

    // check children noedes
    for (auto &child : formNode->children) {
        //std::shared_ptr<TagNode> tagNode = std::dynamic_pointer_cast<TagNode>(child);
        //if (tagNode) {
        result = buildFormData(child, std::move(result));
        //}
    }
    return result;
}

std::unique_ptr<std::vector<Node>> searchNodeTree(const std::shared_ptr<Node> &node, std::unique_ptr<std::vector<Node>> ret) {
    return ret;
}

FormData::FormData(std::shared_ptr<TagNode> start) {
    // recurse down find all interesting tags
    std::unique_ptr<std::vector<Node>> formNodes = std::make_unique<std::vector<Node>>();
    searchNodeTree(start, std::move(formNodes));
}


code:
#ifndef FORMDATA_H
#define FORMDATA_H

#include <string>
#include <map>
#include "../parsers/markup/TagNode.h"

std::unique_ptr<std::map<std::string, std::string>> buildFormData(std::shared_ptr<Node> formNode, std::unique_ptr<std::map<std::string, std::string>> result);
std::unique_ptr<std::vector<Node>> searchNodeTree(const std::shared_ptr<Node> &node, std::unique_ptr<std::vector<Node>> ret);

class FormData {
public:
    FormData();
    FormData(std::shared_ptr<TagNode>);
    // creates arrays out of values
    //void append(std::string name, std::string value);
    //void append(std::string name, std::string value, str::string filename);
    // overwrites value
    //void set(std::string name, std::string value);
    //void set(std::string name, std::string value, str::string filename);
    // gets value (list if array)
    //void getAll(std::string name);
    std::map<std::string, std::string>::iterator entries();
    //std::map<std::string, std::string>::iterator keys();
    //std::map<std::string, std::string>::iterator values();
    std::map<std::string, std::string> data;
};

#endif


code:
#pragma once
#ifndef CACHE_H
#define CACHE_H

#include <unordered_map>
#include <list>
#include <utility>
#include <iostream>
#include <memory>
#include <mutex>

template<class K, class V>
class LRUCache {
	using Key_list = std::list<std::pair<K, std::shared_ptr<V>>>;
	Key_list key_values;
	std::unordered_map<K, typename Key_list::iterator> positions;
	size_t max_values;
	std::mutex cache_mutex;

	void remove_oldest() {
		while (positions.size() >= max_values) {
			positions.erase(key_values.back().first);
			key_values.pop_back();
		}
	}

public:
	LRUCache(const size_t max_values) : max_values(max_values) {
	}

	void insert(const K& key, std::shared_ptr<V> value) {
		std::lock_guard<std::mutex> lock(cache_mutex);
		remove_oldest();
		key_values.emplace_front(key, value);
		positions[key] = key_values.begin();
	}

	void insert(const K& key, V* value) {
		insert(key, std::shared_ptr<V>(value));
	}

	void insert(const K& key, V&& value) {
		insert(key, std::make_shared<V>(std::move(value)));
	}

	void insert(const K& key, V& value) {
		insert(key, std::make_shared<V>(value));
	}

	std::shared_ptr<V> find(const K& key) {
		std::lock_guard<std::mutex> lock(cache_mutex);
		auto p = positions.find(key);
		if (p == positions.end())
			return {};
		auto iter = p->second;
		auto& value = iter->second;
		// If the iterator is not at the front of the list, move it there.
		if (iter != key_values.begin()) {
			key_values.splice(
					key_values.begin(),
					key_values,
					iter,
					std::next(iter));
		}
		positions[key] = key_values.begin();
		return iter->second;
	}

	void debug_cache() {
		std::lock_guard<std::mutex> lock(cache_mutex);
		for (auto& p : key_values) {
			std::cout << p.first << ":" << *p.second << std::endl;
		}
	}
};

#endif