http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-logging/log2gnuplot.py
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-logging/log2gnuplot.py
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-logging/log2gnuplot.py
new file mode 100644
index 0000000..0528259
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-logging/log2gnuplot.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python2
+#
+#  Analyze allocator logs and write total-bytes-in-use after every
+#  operation to stdout.  The output can be gnuplotted as:
+#
+#  $ python log2gnuplot.py </tmp/duk-alloc-log.txt >/tmp/output.txt
+#  $ gnuplot
+#  > plot "output.txt" with lines
+#
+
+import os
+import sys
+
+def main():
+       allocated = 0
+
+       for line in sys.stdin:
+               line = line.strip()
+               parts = line.split(' ')
+
+               # A ptr/NULL/FAIL size
+               # F ptr/NULL size
+               # R ptr/NULL oldsize ptr/NULL/FAIL newsize
+
+               # Note: ajduk doesn't log oldsize (uses -1 instead)
+
+               if parts[0] == 'A':
+                       if parts[1] != 'NULL' and parts[1] != 'FAIL':
+                               allocated += long(parts[2])
+               elif parts[0] == 'F':
+                       allocated -= long(parts[2])
+               elif parts[0] == 'R':
+                       allocated -= long(parts[2])
+                       if parts[3] != 'NULL' and parts[3] != 'FAIL':
+                               allocated += long(parts[4])
+               print(allocated)
+
+       print(allocated)
+
+if __name__ == '__main__':
+       main()

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/README.rst
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/README.rst
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/README.rst
new file mode 100644
index 0000000..f3278bb
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/README.rst
@@ -0,0 +1,10 @@
+==========================================
+Allocator with memory wiping and red zones
+==========================================
+
+Example allocator that wipes memory on free and checks that no out-of-bounds
+writes have been made to bytes just before and after the allocated area.
+
+Valgrind is a better tool for detecting these memory issues, but it's not
+available for all targets so you can use something like this to detect
+memory lifecycle or out-of-bounds issues.

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/duk_alloc_torture.c
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/duk_alloc_torture.c
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/duk_alloc_torture.c
new file mode 100644
index 0000000..abca2f7
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/duk_alloc_torture.c
@@ -0,0 +1,182 @@
+/*
+ *  Example torture memory allocator with memory wiping and check for
+ *  out-of-bounds writes.
+ *
+ *  Allocation structure:
+ *
+ *    [ alloc_hdr | red zone before | user area | red zone after ]
+ *
+ *     ^                             ^
+ *     |                             `--- pointer returned to Duktape
+ *     `--- underlying malloc ptr
+ */
+
+#include "duktape.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#define  RED_ZONE_SIZE  16
+#define  RED_ZONE_BYTE  0x5a
+#define  INIT_BYTE      0xa5
+#define  WIPE_BYTE      0x27
+
+typedef struct {
+       /* The double value in the union is there to ensure alignment is
+        * good for IEEE doubles too.  In many 32-bit environments 4 bytes
+        * would be sufficiently aligned and the double value is unnecessary.
+        */
+       union {
+               size_t sz;
+               double d;
+       } u;
+} alloc_hdr;
+
+static void check_red_zone(alloc_hdr *hdr) {
+       size_t size;
+       int i;
+       int err;
+       unsigned char *p;
+       unsigned char *userptr;
+
+       size = hdr->u.sz;
+       userptr = (unsigned char *) hdr + sizeof(alloc_hdr) + RED_ZONE_SIZE;
+
+       err = 0;
+       p = (unsigned char *) hdr + sizeof(alloc_hdr);
+       for (i = 0; i < RED_ZONE_SIZE; i++) {
+               if (p[i] != RED_ZONE_BYTE) {
+                       err = 1;
+               }
+       }
+       if (err) {
+               fprintf(stderr, "RED ZONE CORRUPTED BEFORE ALLOC: hdr=%p ptr=%p 
size=%ld\n",
+                       (void *) hdr, (void *) userptr, (long) size);
+               fflush(stderr);
+       }
+
+       err = 0;
+       p = (unsigned char *) hdr + sizeof(alloc_hdr) + RED_ZONE_SIZE + size;
+       for (i = 0; i < RED_ZONE_SIZE; i++) {
+               if (p[i] != RED_ZONE_BYTE) {
+                       err = 1;
+               }
+       }
+       if (err) {
+               fprintf(stderr, "RED ZONE CORRUPTED AFTER ALLOC: hdr=%p ptr=%p 
size=%ld\n",
+                       (void *) hdr, (void *) userptr, (long) size);
+               fflush(stderr);
+       }
+}
+
+void *duk_alloc_torture(void *udata, duk_size_t size) {
+       unsigned char *p;
+
+       (void) udata;  /* Suppress warning. */
+
+       if (size == 0) {
+               return NULL;
+       }
+
+       p = (unsigned char *) malloc(size + sizeof(alloc_hdr) + 2 * 
RED_ZONE_SIZE);
+       if (!p) {
+               return NULL;
+       }
+
+       ((alloc_hdr *) (void *) p)->u.sz = size;
+       p += sizeof(alloc_hdr);
+       memset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);
+       p += RED_ZONE_SIZE;
+       memset((void *) p, INIT_BYTE, size);
+       p += size;
+       memset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);
+       p -= size;
+       return (void *) p;
+}
+
+void *duk_realloc_torture(void *udata, void *ptr, duk_size_t size) {
+       unsigned char *p, *old_p;
+       size_t old_size;
+
+       (void) udata;  /* Suppress warning. */
+
+       /* Handle the ptr-NULL vs. size-zero cases explicitly to minimize
+        * platform assumptions.  You can get away with much less in specific
+        * well-behaving environments.
+        */
+
+       if (ptr) {
+               old_p = (unsigned char *) ptr - sizeof(alloc_hdr) - 
RED_ZONE_SIZE;
+               old_size = ((alloc_hdr *) (void *) old_p)->u.sz;
+               check_red_zone((alloc_hdr *) (void *) old_p);
+
+               if (size == 0) {
+                       memset((void *) old_p, WIPE_BYTE, old_size + 
sizeof(alloc_hdr) + 2 * RED_ZONE_SIZE);
+                       free((void *) old_p);
+                       return NULL;
+               } else {
+                       /* Force address change on every realloc. */
+                       p = (unsigned char *) malloc(size + sizeof(alloc_hdr) + 
2 * RED_ZONE_SIZE);
+                       if (!p) {
+                               return NULL;
+                       }
+
+                       ((alloc_hdr *) (void *) p)->u.sz = size;
+                       p += sizeof(alloc_hdr);
+                       memset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);
+                       p += RED_ZONE_SIZE;
+                       if (size > old_size) {
+                               memcpy((void *) p, (void *) (old_p + 
sizeof(alloc_hdr) + RED_ZONE_SIZE), old_size);
+                               memset((void *) (p + old_size), INIT_BYTE, size 
- old_size);
+                       } else {
+                               memcpy((void *) p, (void *) (old_p + 
sizeof(alloc_hdr) + RED_ZONE_SIZE), size);
+                       }
+                       p += size;
+                       memset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);
+                       p -= size;
+
+                       memset((void *) old_p, WIPE_BYTE, old_size + 
sizeof(alloc_hdr) + 2 * RED_ZONE_SIZE);
+                       free((void *) old_p);
+
+                       return (void *) p;
+               }
+       } else {
+               if (size == 0) {
+                       return NULL;
+               } else {
+                       p = (unsigned char *) malloc(size + sizeof(alloc_hdr) + 
2 * RED_ZONE_SIZE);
+                       if (!p) {
+                               return NULL;
+                       }
+
+                       ((alloc_hdr *) (void *) p)->u.sz = size;
+                       p += sizeof(alloc_hdr);
+                       memset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);
+                       p += RED_ZONE_SIZE;
+                       memset((void *) p, INIT_BYTE, size);
+                       p += size;
+                       memset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);
+                       p -= size;
+                       return (void *) p;
+               }
+       }
+}
+
+void duk_free_torture(void *udata, void *ptr) {
+       unsigned char *p;
+       size_t old_size;
+
+       (void) udata;  /* Suppress warning. */
+
+       if (!ptr) {
+               return;
+       }
+
+       p = (unsigned char *) ptr - sizeof(alloc_hdr) - RED_ZONE_SIZE;
+       old_size = ((alloc_hdr *) (void *) p)->u.sz;
+
+       check_red_zone((alloc_hdr *) (void *) p);
+       memset((void *) p, WIPE_BYTE, old_size + sizeof(alloc_hdr) + 2 * 
RED_ZONE_SIZE);
+       free((void *) p);
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/duk_alloc_torture.h
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/duk_alloc_torture.h
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/duk_alloc_torture.h
new file mode 100644
index 0000000..a12153a
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/alloc-torture/duk_alloc_torture.h
@@ -0,0 +1,10 @@
+#ifndef DUK_ALLOC_TORTURE_H_INCLUDED
+#define DUK_ALLOC_TORTURE_H_INCLUDED
+
+#include "duktape.h"
+
+void *duk_alloc_torture(void *udata, duk_size_t size);
+void *duk_realloc_torture(void *udata, void *ptr, duk_size_t size);
+void duk_free_torture(void *udata, void *ptr);
+
+#endif  /* DUK_ALLOC_TORTURE_H_INCLUDED */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/README.rst
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/README.rst
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/README.rst
new file mode 100644
index 0000000..e0c6bce
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/README.rst
@@ -0,0 +1,6 @@
+====================
+Duktape command line
+====================
+
+Ecmascript command line execution tool, useful for running Ecmascript code
+from a file, stdin, or interactively.  Also used by automatic testing.

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/duk_cmdline.c
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/duk_cmdline.c
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/duk_cmdline.c
new file mode 100644
index 0000000..ea5af55
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/duk_cmdline.c
@@ -0,0 +1,1463 @@
+/*
+ *  Command line execution tool.  Useful for test cases and manual testing.
+ *
+ *  To enable linenoise and other fancy stuff, compile with 
-DDUK_CMDLINE_FANCY.
+ *  It is not the default to maximize portability.  You can also compile in
+ *  support for example allocators, grep for DUK_CMDLINE_*.
+ */
+
+/* Helper define to enable a feature set; can also use separate defines. */
+#if defined(DUK_CMDLINE_FANCY)
+#define DUK_CMDLINE_LINENOISE
+#define DUK_CMDLINE_LINENOISE_COMPLETION
+#define DUK_CMDLINE_RLIMIT
+#define DUK_CMDLINE_SIGNAL
+#endif
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || \
+    defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
+/* Suppress warnings about plain fopen() etc. */
+#define _CRT_SECURE_NO_WARNINGS
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+/* Workaround for snprintf() missing in older MSVC versions.
+ * Note that _snprintf() may not NUL terminate the string, but
+ * this difference does not matter here as a NUL terminator is
+ * always explicitly added.
+ */
+#define snprintf _snprintf
+#endif
+#endif
+
+#define  GREET_CODE(variant)  \
+       "print('((o) Duktape" variant " ' + " \
+       "Math.floor(Duktape.version / 10000) + '.' + " \
+       "Math.floor(Duktape.version / 100) % 100 + '.' + " \
+       "Duktape.version % 100" \
+       ", '(" DUK_GIT_DESCRIBE ")');"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(DUK_CMDLINE_SIGNAL)
+#include <signal.h>
+#endif
+#if defined(DUK_CMDLINE_RLIMIT)
+#include <sys/resource.h>
+#endif
+#if defined(DUK_CMDLINE_LINENOISE)
+#include "linenoise.h"
+#endif
+#if defined(DUK_CMDLINE_FILEIO)
+#include <errno.h>
+#endif
+#if defined(EMSCRIPTEN)
+#include <emscripten.h>
+#endif
+#if defined(DUK_CMDLINE_ALLOC_LOGGING)
+#include "duk_alloc_logging.h"
+#endif
+#if defined(DUK_CMDLINE_ALLOC_TORTURE)
+#include "duk_alloc_torture.h"
+#endif
+#if defined(DUK_CMDLINE_ALLOC_HYBRID)
+#include "duk_alloc_hybrid.h"
+#endif
+#include "duktape.h"
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+/* Defined in duk_cmdline_ajduk.c or alljoyn.js headers. */
+void ajsheap_init(void);
+void ajsheap_free(void);
+void ajsheap_dump(void);
+void ajsheap_register(duk_context *ctx);
+void ajsheap_start_exec_timeout(void);
+void ajsheap_clear_exec_timeout(void);
+void *ajsheap_alloc_wrapped(void *udata, duk_size_t size);
+void *ajsheap_realloc_wrapped(void *udata, void *ptr, duk_size_t size);
+void ajsheap_free_wrapped(void *udata, void *ptr);
+void *AJS_Alloc(void *udata, duk_size_t size);
+void *AJS_Realloc(void *udata, void *ptr, duk_size_t size);
+void AJS_Free(void *udata, void *ptr);
+#endif
+
+#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)
+#include "duk_trans_socket.h"
+#endif
+
+#define  MEM_LIMIT_NORMAL   (128*1024*1024)   /* 128 MB */
+#define  MEM_LIMIT_HIGH     (2047*1024*1024)  /* ~2 GB */
+#define  LINEBUF_SIZE       65536
+
+static int main_argc = 0;
+static char **main_argv = NULL;
+static int interactive_mode = 0;
+#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)
+static int debugger_reattach = 0;
+#endif
+
+/*
+ *  Misc helpers
+ */
+
+#if defined(DUK_CMDLINE_RLIMIT)
+static void set_resource_limits(rlim_t mem_limit_value) {
+       int rc;
+       struct rlimit lim;
+
+       rc = getrlimit(RLIMIT_AS, &lim);
+       if (rc != 0) {
+               fprintf(stderr, "Warning: cannot read RLIMIT_AS\n");
+               return;
+       }
+
+       if (lim.rlim_max < mem_limit_value) {
+               fprintf(stderr, "Warning: rlim_max < mem_limit_value (%d < 
%d)\n", (int) lim.rlim_max, (int) mem_limit_value);
+               return;
+       }
+
+       lim.rlim_cur = mem_limit_value;
+       lim.rlim_max = mem_limit_value;
+
+       rc = setrlimit(RLIMIT_AS, &lim);
+       if (rc != 0) {
+               fprintf(stderr, "Warning: setrlimit failed\n");
+               return;
+       }
+
+#if 0
+       fprintf(stderr, "Set RLIMIT_AS to %d\n", (int) mem_limit_value);
+#endif
+}
+#endif  /* DUK_CMDLINE_RLIMIT */
+
+#if defined(DUK_CMDLINE_SIGNAL)
+static void my_sighandler(int x) {
+       fprintf(stderr, "Got signal %d\n", x);
+       fflush(stderr);
+}
+static void set_sigint_handler(void) {
+       (void) signal(SIGINT, my_sighandler);
+       (void) signal(SIGPIPE, SIG_IGN);  /* avoid SIGPIPE killing process */
+}
+#endif  /* DUK_CMDLINE_SIGNAL */
+
+static int get_stack_raw(duk_context *ctx) {
+       if (!duk_is_object(ctx, -1)) {
+               return 1;
+       }
+       if (!duk_has_prop_string(ctx, -1, "stack")) {
+               return 1;
+       }
+       if (!duk_is_error(ctx, -1)) {
+               /* Not an Error instance, don't read "stack". */
+               return 1;
+       }
+
+       duk_get_prop_string(ctx, -1, "stack");  /* caller coerces */
+       duk_remove(ctx, -2);
+       return 1;
+}
+
+/* Print error to stderr and pop error. */
+static void print_pop_error(duk_context *ctx, FILE *f) {
+       /* Print error objects with a stack trace specially.
+        * Note that getting the stack trace may throw an error
+        * so this also needs to be safe call wrapped.
+        */
+       (void) duk_safe_call(ctx, get_stack_raw, 1 /*nargs*/, 1 /*nrets*/);
+       fprintf(f, "%s\n", duk_safe_to_string(ctx, -1));
+       fflush(f);
+       duk_pop(ctx);
+}
+
+static int wrapped_compile_execute(duk_context *ctx) {
+       const char *src_data;
+       duk_size_t src_len;
+       int comp_flags;
+
+       /* XXX: Here it'd be nice to get some stats for the compilation result
+        * when a suitable command line is given (e.g. code size, constant
+        * count, function count.  These are available internally but not 
through
+        * the public API.
+        */
+
+       /* Use duk_compile_lstring_filename() variant which avoids interning
+        * the source code.  This only really matters for low memory 
environments.
+        */
+
+       /* [ ... bytecode_filename src_data src_len filename ] */
+
+       src_data = (const char *) duk_require_pointer(ctx, -3);
+       src_len = (duk_size_t) duk_require_uint(ctx, -2);
+
+       if (src_data != NULL && src_len >= 2 && src_data[0] == (char) 0xff) {
+               /* Bytecode. */
+               duk_push_lstring(ctx, src_data, src_len);
+               duk_to_buffer(ctx, -1, NULL);
+               duk_load_function(ctx);
+       } else {
+               /* Source code. */
+               comp_flags = 0;
+               duk_compile_lstring_filename(ctx, comp_flags, src_data, 
src_len);
+       }
+
+       /* [ ... bytecode_filename src_data src_len function ] */
+
+       /* Optional bytecode dump. */
+       if (duk_is_string(ctx, -4)) {
+               FILE *f;
+               void *bc_ptr;
+               duk_size_t bc_len;
+               size_t wrote;
+               char fnbuf[256];
+               const char *filename;
+
+               duk_dup_top(ctx);
+               duk_dump_function(ctx);
+               bc_ptr = duk_require_buffer(ctx, -1, &bc_len);
+               filename = duk_require_string(ctx, -5);
+#if defined(EMSCRIPTEN)
+               if (filename[0] == '/') {
+                       snprintf(fnbuf, sizeof(fnbuf), "%s", filename);
+               } else {
+                       snprintf(fnbuf, sizeof(fnbuf), "/working/%s", filename);
+               }
+#else
+               snprintf(fnbuf, sizeof(fnbuf), "%s", filename);
+#endif
+               fnbuf[sizeof(fnbuf) - 1] = (char) 0;
+
+               f = fopen(fnbuf, "wb");
+               if (!f) {
+                       duk_error(ctx, DUK_ERR_ERROR, "failed to open bytecode 
output file");
+               }
+               wrote = fwrite(bc_ptr, 1, (size_t) bc_len, f);  /* XXX: handle 
partial writes */
+               (void) fclose(f);
+               if (wrote != bc_len) {
+                       duk_error(ctx, DUK_ERR_ERROR, "failed to write all 
bytecode");
+               }
+
+               return 0;  /* duk_safe_call() cleans up */
+       }
+
+#if 0
+       /* Manual test for bytecode dump/load cycle: dump and load before
+        * execution.  Enable manually, then run "make qecmatest" for a
+        * reasonably good coverage of different functions and programs.
+        */
+       duk_dump_function(ctx);
+       duk_load_function(ctx);
+#endif
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+       ajsheap_start_exec_timeout();
+#endif
+
+       duk_push_global_object(ctx);  /* 'this' binding */
+       duk_call_method(ctx, 0);
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+       ajsheap_clear_exec_timeout();
+#endif
+
+       if (interactive_mode) {
+               /*
+                *  In interactive mode, write to stdout so output won't
+                *  interleave as easily.
+                *
+                *  NOTE: the ToString() coercion may fail in some cases;
+                *  for instance, if you evaluate:
+                *
+                *    ( {valueOf: function() {return {}},
+                *       toString: function() {return {}}});
+                *
+                *  The error is:
+                *
+                *    TypeError: failed to coerce with [[DefaultValue]]
+                *            duk_api.c:1420
+                *
+                *  These are handled now by the caller which also has stack
+                *  trace printing support.  User code can print out errors
+                *  safely using duk_safe_to_string().
+                */
+
+               fprintf(stdout, "= %s\n", duk_to_string(ctx, -1));
+               fflush(stdout);
+       } else {
+               /* In non-interactive mode, success results are not written at 
all.
+                * It is important that the result value is not string coerced,
+                * as the string coercion may cause an error in some cases.
+                */
+       }
+
+       return 0;  /* duk_safe_call() cleans up */
+}
+
+/*
+ *  Minimal Linenoise completion support
+ */
+
+#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)
+static duk_context *completion_ctx;
+
+static int completion_idpart(unsigned char c) {
+       /* Very simplified "is identifier part" check. */
+       if ((c >= (unsigned char) 'a' && c <= (unsigned char) 'z') ||
+           (c >= (unsigned char) 'A' && c <= (unsigned char) 'Z') ||
+           (c >= (unsigned char) '0' && c <= (unsigned char) '9') ||
+           c == (unsigned char) '$' || c == (unsigned char) '_') {
+               return 1;
+       }
+       return 0;
+}
+
+static int completion_digit(unsigned char c) {
+       return (c >= (unsigned char) '0' && c <= (unsigned char) '9');
+}
+
+static duk_ret_t linenoise_completion_lookup(duk_context *ctx) {
+       duk_size_t len;
+       const char *orig;
+       const unsigned char *p;
+       const unsigned char *p_curr;
+       const unsigned char *p_end;
+       const char *key;
+       const char *prefix;
+       linenoiseCompletions *lc;
+       duk_idx_t idx_obj;
+
+       orig = duk_require_string(ctx, -3);
+       p_curr = (const unsigned char *) duk_require_lstring(ctx, -2, &len);
+       p_end = p_curr + len;
+       lc = duk_require_pointer(ctx, -1);
+
+       duk_push_global_object(ctx);
+       idx_obj = duk_require_top_index(ctx);
+
+       while (p_curr <= p_end) {
+               /* p_curr == p_end allowed on purpose, to handle 'Math.' for 
example. */
+               p = p_curr;
+               while (p < p_end && p[0] != (unsigned char) '.') {
+                       p++;
+               }
+               /* 'p' points to a NUL (p == p_end) or a period. */
+               prefix = duk_push_lstring(ctx, (const char *) p_curr, 
(duk_size_t) (p - p_curr));
+
+#if 0
+               fprintf(stderr, "Completion check: '%s'\n", prefix);
+               fflush(stderr);
+#endif
+
+               if (p == p_end) {
+                       /* 'idx_obj' points to the object matching the last
+                        * full component, use [p_curr,p[ as a filter for
+                        * that object.
+                        */
+
+                       duk_enum(ctx, idx_obj, DUK_ENUM_INCLUDE_NONENUMERABLE);
+                       while (duk_next(ctx, -1, 0 /*get_value*/)) {
+                               key = duk_get_string(ctx, -1);
+#if 0
+                               fprintf(stderr, "Key: %s\n", key ? key : "");
+                               fflush(stderr);
+#endif
+                               if (!key) {
+                                       /* Should never happen, just in case. */
+                                       goto next;
+                               }
+
+                               /* Ignore array index keys: usually not 
desirable, and would
+                                * also require ['0'] quoting.
+                                */
+                               if (completion_digit(key[0])) {
+                                       goto next;
+                               }
+
+                               /* XXX: There's no key quoting now, it would 
require replacing the
+                                * last component with a ['foo\nbar'] style 
lookup when appropriate.
+                                */
+
+                               if (strlen(prefix) == 0) {
+                                       /* Partial ends in a period, e.g. 
'Math.' -> complete all Math properties. */
+                                       duk_push_string(ctx, orig);  /* 
original, e.g. 'Math.' */
+                                       duk_push_string(ctx, key);
+                                       duk_concat(ctx, 2);
+                                       linenoiseAddCompletion(lc, 
duk_require_string(ctx, -1));
+                                       duk_pop(ctx);
+                               } else if (prefix && strcmp(key, prefix) == 0) {
+                                       /* Full completion, add a period, e.g. 
input 'Math' -> 'Math.'. */
+                                       duk_push_string(ctx, orig);  /* 
original, including partial last component */
+                                       duk_push_string(ctx, ".");
+                                       duk_concat(ctx, 2);
+                                       linenoiseAddCompletion(lc, 
duk_require_string(ctx, -1));
+                                       duk_pop(ctx);
+                               } else if (prefix && strncmp(key, prefix, 
strlen(prefix)) == 0) {
+                                       /* Last component is partial, complete. 
*/
+                                       duk_push_string(ctx, orig);  /* 
original, including partial last component */
+                                       duk_push_string(ctx, key + 
strlen(prefix));  /* completion to last component */
+                                       duk_concat(ctx, 2);
+                                       linenoiseAddCompletion(lc, 
duk_require_string(ctx, -1));
+                                       duk_pop(ctx);
+                               }
+
+                        next:
+                               duk_pop(ctx);
+                       }
+                       return 0;
+               } else {
+                       if (duk_get_prop(ctx, idx_obj)) {
+                               duk_to_object(ctx, -1);  /* for properties of 
plain strings etc */
+                               duk_replace(ctx, idx_obj);
+                               p_curr = p + 1;
+                       } else {
+                               /* Not found. */
+                               return 0;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static void linenoise_completion(const char *buf, linenoiseCompletions *lc) {
+       duk_context *ctx;
+       const unsigned char *p_start;
+       const unsigned char *p_end;
+       const unsigned char *p;
+       duk_int_t rc;
+
+       if (!buf) {
+               return;
+       }
+       ctx = completion_ctx;
+       if (!ctx) {
+               return;
+       }
+
+       p_start = (const unsigned char *) buf;
+       p_end = (const unsigned char *) (buf + strlen(buf));
+       p = p_end;
+
+       /* Scan backwards for a maximal string which looks like a property
+        * chain (e.g. foo.bar.quux).
+        */
+
+       while (--p >= p_start) {
+               if (p[0] == (unsigned char) '.') {
+                       if (p <= p_start) {
+                               break;
+                       }
+                       if (!completion_idpart(p[-1])) {
+                               /* Catches e.g. 'foo..bar' -> we want 'bar' 
only. */
+                               break;
+                       }
+               } else if (!completion_idpart(p[0])) {
+                       break;
+               }
+       }
+       /* 'p' will either be p_start - 1 (ran out of buffer) or point to
+        * the first offending character.
+        */
+       p++;
+       if (p < p_start || p >= p_end) {
+               return;  /* should never happen, but just in case */
+       }
+
+       /* 'p' now points to a string of the form 'foo.bar.quux'.  Look up
+        * all the components except the last; treat the last component as
+        * a partial name which is used as a filter for the previous full
+        * component.  All lookups are from the global object now.
+        */
+
+#if 0
+       fprintf(stderr, "Completion starting point: '%s'\n", p);
+       fflush(stderr);
+#endif
+
+       duk_push_string(ctx, (const char *) buf);
+       duk_push_lstring(ctx, (const char *) p, (duk_size_t) (p_end - p));
+       duk_push_pointer(ctx, (void *) lc);
+
+       rc = duk_safe_call(ctx, linenoise_completion_lookup, 3 /*nargs*/, 1 
/*nrets*/);
+       if (rc != DUK_EXEC_SUCCESS) {
+               fprintf(stderr, "Completion handling failure: %s\n", 
duk_safe_to_string(ctx, -1));
+       }
+       duk_pop(ctx);
+}
+#endif  /* DUK_CMDLINE_LINENOISE_COMPLETION */
+
+/*
+ *  Execute from file handle etc
+ */
+
+static int handle_fh(duk_context *ctx, FILE *f, const char *filename, const 
char *bytecode_filename) {
+       char *buf = NULL;
+       size_t bufsz;
+       size_t bufoff;
+       size_t got;
+       int rc;
+       int retval = -1;
+
+       buf = (char *) malloc(1024);
+       if (!buf) {
+               goto error;
+       }
+       bufsz = 1024;
+       bufoff = 0;
+
+       /* Read until EOF, avoid fseek/stat because it won't work with stdin. */
+       for (;;) {
+               size_t avail;
+
+               avail = bufsz - bufoff;
+               if (avail < 1024) {
+                       size_t newsz;
+                       char *buf_new;
+#if 0
+                       fprintf(stderr, "resizing read buffer: %ld -> %ld\n", 
(long) bufsz, (long) (bufsz * 2));
+#endif
+                       newsz = bufsz + (bufsz >> 2) + 1024;  /* +25% and some 
extra */
+                       buf_new = (char *) realloc(buf, newsz);
+                       if (!buf_new) {
+                               goto error;
+                       }
+                       buf = buf_new;
+                       bufsz = newsz;
+               }
+
+               avail = bufsz - bufoff;
+#if 0
+               fprintf(stderr, "reading input: buf=%p bufsz=%ld bufoff=%ld 
avail=%ld\n",
+                       (void *) buf, (long) bufsz, (long) bufoff, (long) 
avail);
+#endif
+
+               got = fread((void *) (buf + bufoff), (size_t) 1, avail, f);
+#if 0
+               fprintf(stderr, "got=%ld\n", (long) got);
+#endif
+               if (got == 0) {
+                       break;
+               }
+               bufoff += got;
+
+               /* Emscripten specific: stdin EOF doesn't work as expected.
+                * Instead, when 'emduk' is executed using Node.js, a file
+                * piped to stdin repeats (!).  Detect that repeat and cut off
+                * the stdin read.  Ensure the loop repeats enough times to
+                * avoid detecting spurious loops.
+                *
+                * This only seems to work for inputs up to 256 bytes long.
+                */
+#if defined(EMSCRIPTEN)
+               if (bufoff >= 16384) {
+                       size_t i, j, nloops;
+                       int looped = 0;
+
+                       for (i = 16; i < bufoff / 8; i++) {
+                               int ok;
+
+                               nloops = bufoff / i;
+                               ok = 1;
+                               for (j = 1; j < nloops; j++) {
+                                       if (memcmp((void *) buf, (void *) (buf 
+ i * j), i) != 0) {
+                                               ok = 0;
+                                               break;
+                                       }
+                               }
+                               if (ok) {
+                                       fprintf(stderr, "emscripten workaround: 
detect looping at index %ld, verified with %ld loops\n", (long) i, (long) 
(nloops - 1));
+                                       bufoff = i;
+                                       looped = 1;
+                                       break;
+                               }
+                       }
+
+                       if (looped) {
+                               break;
+                       }
+               }
+#endif
+       }
+
+       duk_push_string(ctx, bytecode_filename);
+       duk_push_pointer(ctx, (void *) buf);
+       duk_push_uint(ctx, (duk_uint_t) bufoff);
+       duk_push_string(ctx, filename);
+
+       interactive_mode = 0;  /* global */
+
+       rc = duk_safe_call(ctx, wrapped_compile_execute, 4 /*nargs*/, 1 
/*nret*/);
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+       ajsheap_clear_exec_timeout();
+#endif
+
+       free(buf);
+       buf = NULL;
+
+       if (rc != DUK_EXEC_SUCCESS) {
+               print_pop_error(ctx, stderr);
+               goto error;
+       } else {
+               duk_pop(ctx);
+               retval = 0;
+       }
+       /* fall thru */
+
+ cleanup:
+       if (buf) {
+               free(buf);
+               buf = NULL;
+       }
+       return retval;
+
+ error:
+       fprintf(stderr, "error in executing file %s\n", filename);
+       fflush(stderr);
+       goto cleanup;
+}
+
+static int handle_file(duk_context *ctx, const char *filename, const char 
*bytecode_filename) {
+       FILE *f = NULL;
+       int retval;
+       char fnbuf[256];
+
+       /* Example of sending an application specific debugger notification. */
+       duk_push_string(ctx, "DebuggerHandleFile");
+       duk_push_string(ctx, filename);
+       duk_debugger_notify(ctx, 2);
+
+#if defined(EMSCRIPTEN)
+       if (filename[0] == '/') {
+               snprintf(fnbuf, sizeof(fnbuf), "%s", filename);
+       } else {
+               snprintf(fnbuf, sizeof(fnbuf), "/working/%s", filename);
+       }
+#else
+       snprintf(fnbuf, sizeof(fnbuf), "%s", filename);
+#endif
+       fnbuf[sizeof(fnbuf) - 1] = (char) 0;
+
+       f = fopen(fnbuf, "rb");
+       if (!f) {
+               fprintf(stderr, "failed to open source file: %s\n", filename);
+               fflush(stderr);
+               goto error;
+       }
+
+       retval = handle_fh(ctx, f, filename, bytecode_filename);
+
+       fclose(f);
+       return retval;
+
+ error:
+       return -1;
+}
+
+static int handle_eval(duk_context *ctx, char *code) {
+       int rc;
+       int retval = -1;
+
+       duk_push_pointer(ctx, (void *) code);
+       duk_push_uint(ctx, (duk_uint_t) strlen(code));
+       duk_push_string(ctx, "eval");
+
+       interactive_mode = 0;  /* global */
+
+       rc = duk_safe_call(ctx, wrapped_compile_execute, 3 /*nargs*/, 1 
/*nret*/);
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+       ajsheap_clear_exec_timeout();
+#endif
+
+       if (rc != DUK_EXEC_SUCCESS) {
+               print_pop_error(ctx, stderr);
+       } else {
+               duk_pop(ctx);
+               retval = 0;
+       }
+
+       return retval;
+}
+
+#if defined(DUK_CMDLINE_LINENOISE)
+static int handle_interactive(duk_context *ctx) {
+       const char *prompt = "duk> ";
+       char *buffer = NULL;
+       int retval = 0;
+       int rc;
+
+       duk_eval_string(ctx, GREET_CODE(" [linenoise]"));
+       duk_pop(ctx);
+
+       linenoiseSetMultiLine(1);
+       linenoiseHistorySetMaxLen(64);
+#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)
+       linenoiseSetCompletionCallback(linenoise_completion);
+#endif
+
+       for (;;) {
+               if (buffer) {
+                       linenoiseFree(buffer);
+                       buffer = NULL;
+               }
+
+#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)
+               completion_ctx = ctx;
+#endif
+               buffer = linenoise(prompt);
+#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)
+               completion_ctx = NULL;
+#endif
+
+               if (!buffer) {
+                       break;
+               }
+
+               if (buffer && buffer[0] != (char) 0) {
+                       linenoiseHistoryAdd(buffer);
+               }
+
+               duk_push_pointer(ctx, (void *) buffer);
+               duk_push_uint(ctx, (duk_uint_t) strlen(buffer));
+               duk_push_string(ctx, "input");
+
+               interactive_mode = 1;  /* global */
+
+               rc = duk_safe_call(ctx, wrapped_compile_execute, 3 /*nargs*/, 1 
/*nret*/);
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+               ajsheap_clear_exec_timeout();
+#endif
+
+               if (buffer) {
+                       linenoiseFree(buffer);
+                       buffer = NULL;
+               }
+
+               if (rc != DUK_EXEC_SUCCESS) {
+                       /* in interactive mode, write to stdout */
+                       print_pop_error(ctx, stdout);
+                       retval = -1;  /* an error 'taints' the execution */
+               } else {
+                       duk_pop(ctx);
+               }
+       }
+
+       if (buffer) {
+               linenoiseFree(buffer);
+               buffer = NULL;
+       }
+
+       return retval;
+}
+#else  /* DUK_CMDLINE_LINENOISE */
+static int handle_interactive(duk_context *ctx) {
+       const char *prompt = "duk> ";
+       char *buffer = NULL;
+       int retval = 0;
+       int rc;
+       int got_eof = 0;
+
+       duk_eval_string(ctx, GREET_CODE(""));
+       duk_pop(ctx);
+
+       buffer = (char *) malloc(LINEBUF_SIZE);
+       if (!buffer) {
+               fprintf(stderr, "failed to allocated a line buffer\n");
+               fflush(stderr);
+               retval = -1;
+               goto done;
+       }
+
+       while (!got_eof) {
+               size_t idx = 0;
+
+               fwrite(prompt, 1, strlen(prompt), stdout);
+               fflush(stdout);
+
+               for (;;) {
+                       int c = fgetc(stdin);
+                       if (c == EOF) {
+                               got_eof = 1;
+                               break;
+                       } else if (c == '\n') {
+                               break;
+                       } else if (idx >= LINEBUF_SIZE) {
+                               fprintf(stderr, "line too long\n");
+                               fflush(stderr);
+                               retval = -1;
+                               goto done;
+                       } else {
+                               buffer[idx++] = (char) c;
+                       }
+               }
+
+               duk_push_pointer(ctx, (void *) buffer);
+               duk_push_uint(ctx, (duk_uint_t) idx);
+               duk_push_string(ctx, "input");
+
+               interactive_mode = 1;  /* global */
+
+               rc = duk_safe_call(ctx, wrapped_compile_execute, 3 /*nargs*/, 1 
/*nret*/);
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+               ajsheap_clear_exec_timeout();
+#endif
+
+               if (rc != DUK_EXEC_SUCCESS) {
+                       /* in interactive mode, write to stdout */
+                       print_pop_error(ctx, stdout);
+                       retval = -1;  /* an error 'taints' the execution */
+               } else {
+                       duk_pop(ctx);
+               }
+       }
+
+ done:
+       if (buffer) {
+               free(buffer);
+               buffer = NULL;
+       }
+
+       return retval;
+}
+#endif  /* DUK_CMDLINE_LINENOISE */
+
+/*
+ *  Simple file read/write bindings
+ */
+
+#if defined(DUK_CMDLINE_FILEIO)
+static duk_ret_t fileio_read_file(duk_context *ctx) {
+       const char *fn;
+       char *buf;
+       size_t len;
+       size_t off;
+       int rc;
+       FILE *f;
+
+       fn = duk_require_string(ctx, 0);
+       f = fopen(fn, "rb");
+       if (!f) {
+               duk_error(ctx, DUK_ERR_TYPE_ERROR, "cannot open file %s for 
reading, errno %ld: %s",
+                         fn, (long) errno, strerror(errno));
+       }
+
+       rc = fseek(f, 0, SEEK_END);
+       if (rc < 0) {
+               (void) fclose(f);
+               duk_error(ctx, DUK_ERR_TYPE_ERROR, "fseek() failed for %s, 
errno %ld: %s",
+                         fn, (long) errno, strerror(errno));
+       }
+       len = (size_t) ftell(f);
+       rc = fseek(f, 0, SEEK_SET);
+       if (rc < 0) {
+               (void) fclose(f);
+               duk_error(ctx, DUK_ERR_TYPE_ERROR, "fseek() failed for %s, 
errno %ld: %s",
+                         fn, (long) errno, strerror(errno));
+       }
+
+       buf = (char *) duk_push_fixed_buffer(ctx, (duk_size_t) len);
+       for (off = 0; off < len;) {
+               size_t got;
+               got = fread((void *) (buf + off), 1, len - off, f);
+               if (ferror(f)) {
+                       (void) fclose(f);
+                       duk_error(ctx, DUK_ERR_TYPE_ERROR, "error while reading 
%s", fn);
+               }
+               if (got == 0) {
+                       if (feof(f)) {
+                               break;
+                       } else {
+                               (void) fclose(f);
+                               duk_error(ctx, DUK_ERR_TYPE_ERROR, "error while 
reading %s", fn);
+                       }
+               }
+               off += got;
+       }
+
+       if (f) {
+               (void) fclose(f);
+       }
+
+       return 1;
+}
+
+static duk_ret_t fileio_write_file(duk_context *ctx) {
+       const char *fn;
+       const char *buf;
+       size_t len;
+       size_t off;
+       FILE *f;
+
+       fn = duk_require_string(ctx, 0);
+       f = fopen(fn, "wb");
+       if (!f) {
+               duk_error(ctx, DUK_ERR_TYPE_ERROR, "cannot open file %s for 
writing, errno %ld: %s",
+                         fn, (long) errno, strerror(errno));
+       }
+
+       len = 0;
+       buf = (char *) duk_to_buffer(ctx, 1, &len);
+       for (off = 0; off < len;) {
+               size_t got;
+               got = fwrite((const void *) (buf + off), 1, len - off, f);
+               if (ferror(f)) {
+                       (void) fclose(f);
+                       duk_error(ctx, DUK_ERR_TYPE_ERROR, "error while writing 
%s", fn);
+               }
+               if (got == 0) {
+                       (void) fclose(f);
+                       duk_error(ctx, DUK_ERR_TYPE_ERROR, "error while writing 
%s", fn);
+               }
+               off += got;
+       }
+
+       if (f) {
+               (void) fclose(f);
+       }
+
+       return 0;
+}
+#endif  /* DUK_CMDLINE_FILEIO */
+
+/*
+ *  Duktape heap lifecycle
+ */
+
+#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)
+static duk_idx_t debugger_request(duk_context *ctx, void *udata, duk_idx_t 
nvalues) {
+       const char *cmd;
+       int i;
+
+       (void) udata;
+
+       if (nvalues < 1) {
+               duk_push_string(ctx, "missing AppRequest argument(s)");
+               return -1;
+       }
+
+       cmd = duk_get_string(ctx, -nvalues + 0);
+
+       if (cmd && strcmp(cmd, "CommandLine") == 0) {
+               if (!duk_check_stack(ctx, main_argc)) {
+                       /* Callback should avoid errors for now, so use
+                        * duk_check_stack() rather than duk_require_stack().
+                        */
+                       duk_push_string(ctx, "failed to extend stack");
+                       return -1;
+               }
+               for (i = 0; i < main_argc; i++) {
+                       duk_push_string(ctx, main_argv[i]);
+               }
+               return main_argc;
+       }
+       duk_push_sprintf(ctx, "command not supported");
+       return -1;
+}
+
+static void debugger_detached(void *udata) {
+       duk_context *ctx = (duk_context *) udata;
+       (void) ctx;
+       fprintf(stderr, "Debugger detached, udata: %p\n", (void *) udata);
+       fflush(stderr);
+
+       /* Ensure socket is closed even when detach is initiated by Duktape
+        * rather than debug client.
+        */
+        duk_trans_socket_finish();
+
+       if (debugger_reattach) {
+               /* For automatic reattach testing. */
+               duk_trans_socket_init();
+               duk_trans_socket_waitconn();
+               fprintf(stderr, "Debugger reconnected, call 
duk_debugger_attach()\n");
+               fflush(stderr);
+#if 0
+               /* This is not necessary but should be harmless. */
+               duk_debugger_detach(ctx);
+#endif
+               duk_debugger_attach_custom(ctx,
+                                          duk_trans_socket_read_cb,
+                                          duk_trans_socket_write_cb,
+                                          duk_trans_socket_peek_cb,
+                                          duk_trans_socket_read_flush_cb,
+                                          duk_trans_socket_write_flush_cb,
+                                          debugger_request,
+                                          debugger_detached,
+                                          (void *) ctx);
+       }
+}
+#endif
+
+#define  ALLOC_DEFAULT  0
+#define  ALLOC_LOGGING  1
+#define  ALLOC_TORTURE  2
+#define  ALLOC_HYBRID   3
+#define  ALLOC_AJSHEAP  4
+
+static duk_context *create_duktape_heap(int alloc_provider, int debugger, int 
ajsheap_log) {
+       duk_context *ctx;
+
+       (void) ajsheap_log;  /* suppress warning */
+
+       ctx = NULL;
+       if (!ctx && alloc_provider == ALLOC_LOGGING) {
+#if defined(DUK_CMDLINE_ALLOC_LOGGING)
+               ctx = duk_create_heap(duk_alloc_logging,
+                                     duk_realloc_logging,
+                                     duk_free_logging,
+                                     (void *) 0xdeadbeef,
+                                     NULL);
+#else
+               fprintf(stderr, "Warning: option --alloc-logging ignored, no 
logging allocator support\n");
+               fflush(stderr);
+#endif
+       }
+       if (!ctx && alloc_provider == ALLOC_TORTURE) {
+#if defined(DUK_CMDLINE_ALLOC_TORTURE)
+               ctx = duk_create_heap(duk_alloc_torture,
+                                     duk_realloc_torture,
+                                     duk_free_torture,
+                                     (void *) 0xdeadbeef,
+                                     NULL);
+#else
+               fprintf(stderr, "Warning: option --alloc-torture ignored, no 
torture allocator support\n");
+               fflush(stderr);
+#endif
+       }
+       if (!ctx && alloc_provider == ALLOC_HYBRID) {
+#if defined(DUK_CMDLINE_ALLOC_HYBRID)
+               void *udata = duk_alloc_hybrid_init();
+               if (!udata) {
+                       fprintf(stderr, "Failed to init hybrid allocator\n");
+                       fflush(stderr);
+               } else {
+                       ctx = duk_create_heap(duk_alloc_hybrid,
+                                             duk_realloc_hybrid,
+                                             duk_free_hybrid,
+                                             udata,
+                                             NULL);
+               }
+#else
+               fprintf(stderr, "Warning: option --alloc-hybrid ignored, no 
hybrid allocator support\n");
+               fflush(stderr);
+#endif
+       }
+       if (!ctx && alloc_provider == ALLOC_AJSHEAP) {
+#if defined(DUK_CMDLINE_AJSHEAP)
+               ajsheap_init();
+
+               ctx = duk_create_heap(
+                       ajsheap_log ? ajsheap_alloc_wrapped : AJS_Alloc,
+                       ajsheap_log ? ajsheap_realloc_wrapped : AJS_Realloc,
+                       ajsheap_log ? ajsheap_free_wrapped : AJS_Free,
+                       (void *) 0xdeadbeef,  /* heap_udata: ignored by 
AjsHeap, use as marker */
+                       NULL
+               );                /* fatal_handler */
+#else
+               fprintf(stderr, "Warning: option --alloc-ajsheap ignored, no 
ajsheap allocator support\n");
+               fflush(stderr);
+#endif
+       }
+       if (!ctx && alloc_provider == ALLOC_DEFAULT) {
+               ctx = duk_create_heap_default();
+       }
+
+       if (!ctx) {
+               fprintf(stderr, "Failed to create Duktape heap\n");
+               fflush(stderr);
+               exit(-1);
+       }
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+       if (alloc_provider == ALLOC_AJSHEAP) {
+               fprintf(stdout, "Pool dump after heap creation\n");
+               ajsheap_dump();
+       }
+#endif
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+       if (alloc_provider == ALLOC_AJSHEAP) {
+               ajsheap_register(ctx);
+       }
+#endif
+
+#if defined(DUK_CMDLINE_FILEIO)
+       duk_push_c_function(ctx, fileio_read_file, 1 /*nargs*/);
+       duk_put_global_string(ctx, "readFile");
+       duk_push_c_function(ctx, fileio_write_file, 2 /*nargs*/);
+       duk_put_global_string(ctx, "writeFile");
+#endif
+
+       if (debugger) {
+#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)
+               fprintf(stderr, "Debugger enabled, create socket and wait for 
connection\n");
+               fflush(stderr);
+               duk_trans_socket_init();
+               duk_trans_socket_waitconn();
+               fprintf(stderr, "Debugger connected, call duk_debugger_attach() 
and then execute requested file(s)/eval\n");
+               fflush(stderr);
+               duk_debugger_attach_custom(ctx,
+                                          duk_trans_socket_read_cb,
+                                          duk_trans_socket_write_cb,
+                                          duk_trans_socket_peek_cb,
+                                          duk_trans_socket_read_flush_cb,
+                                          duk_trans_socket_write_flush_cb,
+                                          debugger_request,
+                                          debugger_detached,
+                                          (void *) ctx);
+#else
+               fprintf(stderr, "Warning: option --debugger ignored, no 
debugger support\n");
+               fflush(stderr);
+#endif
+       }
+
+#if 0
+       /* Manual test for duk_debugger_cooperate() */
+       {
+               for (i = 0; i < 60; i++) {
+                       printf("cooperate: %d\n", i);
+                       usleep(1000000);
+                       duk_debugger_cooperate(ctx);
+               }
+       }
+#endif
+
+       return ctx;
+}
+
+static void destroy_duktape_heap(duk_context *ctx, int alloc_provider) {
+       (void) alloc_provider;
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+       if (alloc_provider == ALLOC_AJSHEAP) {
+               fprintf(stdout, "Pool dump before duk_destroy_heap(), before 
forced gc\n");
+               ajsheap_dump();
+
+               duk_gc(ctx, 0);
+
+               fprintf(stdout, "Pool dump before duk_destroy_heap(), after 
forced gc\n");
+               ajsheap_dump();
+       }
+#endif
+
+       if (ctx) {
+               duk_destroy_heap(ctx);
+       }
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+       if (alloc_provider == ALLOC_AJSHEAP) {
+               fprintf(stdout, "Pool dump after duk_destroy_heap() (should 
have zero allocs)\n");
+               ajsheap_dump();
+       }
+       ajsheap_free();
+#endif
+}
+
+/*
+ *  Main
+ */
+
+int main(int argc, char *argv[]) {
+       duk_context *ctx = NULL;
+       int retval = 0;
+       int have_files = 0;
+       int have_eval = 0;
+       int interactive = 0;
+       int memlimit_high = 1;
+       int alloc_provider = ALLOC_DEFAULT;
+       int ajsheap_log = 0;
+       int debugger = 0;
+       int recreate_heap = 0;
+       int no_heap_destroy = 0;
+       int verbose = 0;
+       int run_stdin = 0;
+       const char *compile_filename = NULL;
+       int i;
+
+       main_argc = argc;
+       main_argv = (char **) argv;
+
+#if defined(EMSCRIPTEN)
+       /* Try to use NODEFS to provide access to local files.  Mount the
+        * CWD as /working, and then prepend "/working/" to relative native
+        * paths in file calls to get something that works reasonably for
+        * relative paths.  Emscripten doesn't support replacing virtual
+        * "/" with host "/" (the default MEMFS at "/" can't be unmounted)
+        * but we can mount "/tmp" as host "/tmp" to allow testcase runs.
+        *
+        * 
https://kripken.github.io/emscripten-site/docs/api_reference/Filesystem-API.html#filesystem-api-nodefs
+        * 
https://github.com/kripken/emscripten/blob/master/tests/fs/test_nodefs_rw.c
+        */
+       EM_ASM(
+               /* At the moment it's not possible to replace the default MEMFS 
mounted at '/':
+                * https://github.com/kripken/emscripten/issues/2040
+                * 
https://github.com/kripken/emscripten/blob/incoming/src/library_fs.js#L1341-L1358
+                */
+               /*
+               try {
+                       FS.unmount("/");
+               } catch (e) {
+                       console.log("Failed to unmount default '/' MEMFS mount: 
" + e);
+               }
+               */
+               try {
+                       FS.mkdir("/working");
+                       FS.mount(NODEFS, { root: "." }, "/working");
+               } catch (e) {
+                       console.log("Failed to mount NODEFS /working: " + e);
+               }
+               /* A virtual '/tmp' exists by default:
+                * 
https://gist.github.com/evanw/e6be28094f34451bd5bd#file-temp-js-L3806-L3809
+                */
+               /*
+               try {
+                       FS.mkdir("/tmp");
+               } catch (e) {
+                       console.log("Failed to create virtual /tmp: " + e);
+               }
+               */
+               try {
+                       FS.mount(NODEFS, { root: "/tmp" }, "/tmp");
+               } catch (e) {
+                       console.log("Failed to mount NODEFS /tmp: " + e);
+               }
+       );
+#endif  /* EMSCRIPTEN */
+
+#if defined(DUK_CMDLINE_AJSHEAP)
+       alloc_provider = ALLOC_AJSHEAP;
+#endif
+       (void) ajsheap_log;
+
+       /*
+        *  Signal handling setup
+        */
+
+#if defined(DUK_CMDLINE_SIGNAL)
+       set_sigint_handler();
+
+       /* This is useful at the global level; libraries should avoid SIGPIPE 
though */
+       /*signal(SIGPIPE, SIG_IGN);*/
+#endif
+
+       /*
+        *  Parse options
+        */
+
+       for (i = 1; i < argc; i++) {
+               char *arg = argv[i];
+               if (!arg) {
+                       goto usage;
+               }
+               if (strcmp(arg, "--restrict-memory") == 0) {
+                       memlimit_high = 0;
+               } else if (strcmp(arg, "-i") == 0) {
+                       interactive = 1;
+               } else if (strcmp(arg, "-c") == 0) {
+                       if (i == argc - 1) {
+                               goto usage;
+                       }
+                       i++;
+                       compile_filename = argv[i];
+               } else if (strcmp(arg, "-e") == 0) {
+                       have_eval = 1;
+                       if (i == argc - 1) {
+                               goto usage;
+                       }
+                       i++;  /* skip code */
+               } else if (strcmp(arg, "--alloc-default") == 0) {
+                       alloc_provider = ALLOC_DEFAULT;
+               } else if (strcmp(arg, "--alloc-logging") == 0) {
+                       alloc_provider = ALLOC_LOGGING;
+               } else if (strcmp(arg, "--alloc-torture") == 0) {
+                       alloc_provider = ALLOC_TORTURE;
+               } else if (strcmp(arg, "--alloc-hybrid") == 0) {
+                       alloc_provider = ALLOC_HYBRID;
+               } else if (strcmp(arg, "--alloc-ajsheap") == 0) {
+                       alloc_provider = ALLOC_AJSHEAP;
+               } else if (strcmp(arg, "--ajsheap-log") == 0) {
+                       ajsheap_log = 1;
+               } else if (strcmp(arg, "--debugger") == 0) {
+                       debugger = 1;
+#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)
+               } else if (strcmp(arg, "--reattach") == 0) {
+                       debugger_reattach = 1;
+#endif
+               } else if (strcmp(arg, "--recreate-heap") == 0) {
+                       recreate_heap = 1;
+               } else if (strcmp(arg, "--no-heap-destroy") == 0) {
+                       no_heap_destroy = 1;
+               } else if (strcmp(arg, "--verbose") == 0) {
+                       verbose = 1;
+               } else if (strcmp(arg, "--run-stdin") == 0) {
+                       run_stdin = 1;
+               } else if (strlen(arg) >= 1 && arg[0] == '-') {
+                       goto usage;
+               } else {
+                       have_files = 1;
+               }
+       }
+       if (!have_files && !have_eval && !run_stdin) {
+               interactive = 1;
+       }
+
+       /*
+        *  Memory limit
+        */
+
+#if defined(DUK_CMDLINE_RLIMIT)
+       set_resource_limits(memlimit_high ? MEM_LIMIT_HIGH : MEM_LIMIT_NORMAL);
+#else
+       if (memlimit_high == 0) {
+               fprintf(stderr, "Warning: option --restrict-memory ignored, no 
rlimit support\n");
+               fflush(stderr);
+       }
+#endif
+
+       /*
+        *  Create heap
+        */
+
+       ctx = create_duktape_heap(alloc_provider, debugger, ajsheap_log);
+
+       /*
+        *  Execute any argument file(s)
+        */
+
+       for (i = 1; i < argc; i++) {
+               char *arg = argv[i];
+               if (!arg) {
+                       continue;
+               } else if (strlen(arg) == 2 && strcmp(arg, "-e") == 0) {
+                       /* Here we know the eval arg exists but check anyway */
+                       if (i == argc - 1) {
+                               retval = 1;
+                               goto cleanup;
+                       }
+                       if (handle_eval(ctx, argv[i + 1]) != 0) {
+                               retval = 1;
+                               goto cleanup;
+                       }
+                       i++;  /* skip code */
+                       continue;
+               } else if (strlen(arg) == 2 && strcmp(arg, "-c") == 0) {
+                       i++;  /* skip filename */
+                       continue;
+               } else if (strlen(arg) >= 1 && arg[0] == '-') {
+                       continue;
+               }
+
+               if (verbose) {
+                       fprintf(stderr, "*** Executing file: %s\n", arg);
+                       fflush(stderr);
+               }
+
+               if (handle_file(ctx, arg, compile_filename) != 0) {
+                       retval = 1;
+                       goto cleanup;
+               }
+
+               if (recreate_heap) {
+                       if (verbose) {
+                               fprintf(stderr, "*** Recreating heap...\n");
+                               fflush(stderr);
+                       }
+
+                       destroy_duktape_heap(ctx, alloc_provider);
+                       ctx = create_duktape_heap(alloc_provider, debugger, 
ajsheap_log);
+               }
+       }
+
+       if (run_stdin) {
+               /* Running stdin like a full file (reading all lines before
+                * compiling) is useful with emduk:
+                * cat test.js | ./emduk --run-stdin
+                */
+               if (handle_fh(ctx, stdin, "stdin", compile_filename) != 0) {
+                       retval = 1;
+                       goto cleanup;
+               }
+
+               if (recreate_heap) {
+                       if (verbose) {
+                               fprintf(stderr, "*** Recreating heap...\n");
+                               fflush(stderr);
+                       }
+
+                       destroy_duktape_heap(ctx, alloc_provider);
+                       ctx = create_duktape_heap(alloc_provider, debugger, 
ajsheap_log);
+               }
+       }
+
+       /*
+        *  Enter interactive mode if options indicate it
+        */
+
+       if (interactive) {
+               if (handle_interactive(ctx) != 0) {
+                       retval = 1;
+                       goto cleanup;
+               }
+       }
+
+       /*
+        *  Cleanup and exit
+        */
+
+ cleanup:
+       if (interactive) {
+               fprintf(stderr, "Cleaning up...\n");
+               fflush(stderr);
+       }
+
+       if (ctx && no_heap_destroy) {
+               duk_gc(ctx, 0);
+       }
+       if (ctx && !no_heap_destroy) {
+               destroy_duktape_heap(ctx, alloc_provider);
+       }
+       ctx = NULL;
+
+       return retval;
+
+       /*
+        *  Usage
+        */
+
+ usage:
+       fprintf(stderr, "Usage: duk [options] [<filenames>]\n"
+                       "\n"
+                       "   -i                 enter interactive mode after 
executing argument file(s) / eval code\n"
+                       "   -e CODE            evaluate code\n"
+                       "   -c FILE            compile into bytecode (use with 
only one file argument)\n"
+                       "   --run-stdin        treat stdin like a file, i.e. 
compile full input (not line by line)\n"
+                       "   --verbose          verbose messages to stderr\n"
+                       "   --restrict-memory  use lower memory limit (used by 
test runner)\n"
+                       "   --alloc-default    use Duktape default allocator\n"
+#if defined(DUK_CMDLINE_ALLOC_LOGGING)
+                       "   --alloc-logging    use logging allocator (writes to 
/tmp)\n"
+#endif
+#if defined(DUK_CMDLINE_ALLOC_TORTURE)
+                       "   --alloc-torture    use torture allocator\n"
+#endif
+#if defined(DUK_CMDLINE_ALLOC_HYBRID)
+                       "   --alloc-hybrid     use hybrid allocator\n"
+#endif
+#if defined(DUK_CMDLINE_AJSHEAP)
+                       "   --alloc-ajsheap    use ajsheap allocator (enabled 
by default with 'ajduk')\n"
+                       "   --ajsheap-log      write alloc log to 
/tmp/ajduk-alloc-log.txt\n"
+#endif
+#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)
+                       "   --debugger         start example debugger\n"
+                       "   --reattach         automatically reattach debugger 
on detach\n"
+#endif
+                       "   --recreate-heap    recreate heap after every file\n"
+                       "   --no-heap-destroy  force GC, but don't destroy heap 
at end (leak testing)\n"
+                       "\n"
+                       "If <filename> is omitted, interactive mode is started 
automatically.\n");
+       fflush(stderr);
+       exit(1);
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/duk_cmdline_ajduk.c
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/duk_cmdline_ajduk.c
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/duk_cmdline_ajduk.c
new file mode 100644
index 0000000..ae28ede
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/cmdline/duk_cmdline_ajduk.c
@@ -0,0 +1,1008 @@
+/*
+ *  'ajduk' specific functionality, examples for low memory techniques
+ */
+
+#ifdef DUK_CMDLINE_AJSHEAP
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "ajs.h"
+#include "ajs_heap.h"
+#include "duktape.h"
+
+extern uint8_t dbgHEAPDUMP;
+
+#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)
+/* Pointer compression with ROM strings/objects:
+ *
+ * For now, use DUK_USE_ROM_OBJECTS to signal the need for compressed ROM
+ * pointers.  DUK_USE_ROM_PTRCOMP_FIRST is provided for the ROM pointer
+ * compression range minimum to avoid duplication in user code.
+ */
+#if 0  /* This extern declaration is provided by duktape.h, array provided by 
duktape.c. */
+extern const void * const duk_rom_compressed_pointers[];
+#endif
+static const void *duk__romptr_low = NULL;
+static const void *duk__romptr_high = NULL;
+#define DUK__ROMPTR_COMPRESSION
+#define DUK__ROMPTR_FIRST DUK_USE_ROM_PTRCOMP_FIRST
+#endif
+
+/*
+ *  Helpers
+ */
+
+static void *ajduk__lose_const(const void *ptr) {
+       /* Somewhat portable way of losing a const without warnings.
+        * Another approach is to cast through intptr_t, but that
+        * type is not always available.
+        */
+       union {
+               const void *p;
+               void *q;
+       } u;
+       u.p = ptr;
+       return u.q;
+}
+
+static void safe_print_chars(const char *p, duk_size_t len, int until_nul) {
+       duk_size_t i;
+
+       printf("\"");
+       for (i = 0; i < len; i++) {
+               unsigned char x = (unsigned char) p[i];
+               if (until_nul && x == 0U) {
+                       break;
+               }
+               if (x < 0x20 || x >= 0x7e || x == '"' || x == '\'' || x == 
'\\') {
+                       printf("\\x%02x", (int) x);
+               } else {
+                       printf("%c", (char) x);
+               }
+       }
+       printf("\"");
+}
+
+/*
+ *  Heap initialization when using AllJoyn.js pool allocator (without any
+ *  other AllJoyn.js integration).  This serves as an example of how to
+ *  integrate Duktape with a pool allocator and is useful for low memory
+ *  testing.
+ *
+ *  The pool sizes are not optimized here.  The sizes are chosen so that
+ *  you can look at the high water mark (hwm) and use counts (use) and see
+ *  how much allocations are needed for each pool size.  To optimize pool
+ *  sizes more accurately, you can use --alloc-logging and inspect the memory
+ *  allocation log which provides exact byte counts etc.
+ *
+ *  https://git.allseenalliance.org/cgit/core/alljoyn-js.git
+ *  https://git.allseenalliance.org/cgit/core/alljoyn-js.git/tree/ajs.c
+ */
+
+static const AJS_HeapConfig ajsheap_config[] = {
+       { 8,      10,   AJS_POOL_BORROW,  0 },
+       { 12,     600,  AJS_POOL_BORROW,  0 },
+       { 16,     300,  AJS_POOL_BORROW,  0 },
+       { 20,     300,  AJS_POOL_BORROW,  0 },
+       { 24,     300,  AJS_POOL_BORROW,  0 },
+       { 28,     150,  AJS_POOL_BORROW,  0 },
+       { 32,     150,  AJS_POOL_BORROW,  0 },
+       { 40,     150,  AJS_POOL_BORROW,  0 },
+       { 48,     50,   AJS_POOL_BORROW,  0 },
+       { 52,     50,   AJS_POOL_BORROW,  0 },
+       { 56,     50,   AJS_POOL_BORROW,  0 },
+       { 60,     50,   AJS_POOL_BORROW,  0 },
+       { 64,     50,   AJS_POOL_BORROW,  0 },
+       { 128,    80,   AJS_POOL_BORROW,  0 },
+       { 256,    16,   AJS_POOL_BORROW,  0 },
+       { 320,    1,    AJS_POOL_BORROW,  0 },
+       { 392,    1,    AJS_POOL_BORROW,  0 },  /* duk_hthread, with heap ptr 
compression, ROM strings+objects */
+       { 512,    16,   AJS_POOL_BORROW,  0 },
+       { 964,    1,    AJS_POOL_BORROW,  0 },  /* duk_heap, with heap ptr 
compression, ROM strings+objects */
+       { 1024,   6,    AJS_POOL_BORROW,  0 },
+       { 1344,   1,    AJS_POOL_BORROW,  0 },  /* duk_heap, with heap ptr 
compression, RAM strings+objects */
+       { 2048,   5,    AJS_POOL_BORROW,  0 },
+       { 4096,   3,    0,                0 },
+       { 8192,   3,    0,                0 },
+       { 16384,  1,    0,                0 },
+       { 32768,  1,    0,                0 }
+};
+
+uint8_t *ajsheap_ram = NULL;
+
+void ajsheap_init(void) {
+       size_t heap_sz[1];
+       uint8_t *heap_array[1];
+       uint8_t num_pools, i;
+       AJ_Status ret;
+
+       num_pools = (uint8_t) (sizeof(ajsheap_config) / sizeof(AJS_HeapConfig));
+       heap_sz[0] = AJS_HeapRequired(ajsheap_config,  /* heapConfig */
+                                     num_pools,       /* numPools */
+                                     0);              /* heapNum */
+       ajsheap_ram = (uint8_t *) malloc(heap_sz[0]);
+       if (ajsheap_ram == NULL) {
+               fprintf(stderr, "Failed to allocate AJS heap\n");
+               fflush(stderr);
+               exit(1);
+       }
+       heap_array[0] = ajsheap_ram;
+
+       fprintf(stderr, "Allocated AJS heap of %ld bytes, pools:", (long) 
heap_sz[0]);
+       for (i = 0; i < num_pools; i++) {
+               fprintf(stderr, " (sz:%ld,num:%ld,brw:%ld,idx:%ld)",
+                       (long) ajsheap_config[i].size, (long) 
ajsheap_config[i].entries,
+                       (long) ajsheap_config[i].borrow, (long) 
ajsheap_config[i].heapIndex);
+       }
+       fprintf(stderr, "\n");
+       fflush(stderr);
+
+       ret = AJS_HeapInit((void **) heap_array,   /* heap */
+                          (size_t *) heap_sz,     /* heapSz */
+                          ajsheap_config,         /* heapConfig */
+                          num_pools,              /* numPools */
+                          1);                     /* numHeaps */
+       fprintf(stderr, "AJS_HeapInit() -> %ld\n", (long) ret);
+       fflush(stderr);
+
+       /* Enable heap dumps */
+       dbgHEAPDUMP = 1;
+
+#if defined(DUK__ROMPTR_COMPRESSION)
+       /* Scan ROM pointer range for faster detection of "is 'p' a ROM pointer"
+        * later on.
+        */
+       if (1) {
+               const void * const * ptrs = (const void * const *) 
duk_rom_compressed_pointers;
+               duk__romptr_low = duk__romptr_high = (const void *) *ptrs;
+               while (*ptrs) {
+                       if (*ptrs > duk__romptr_high) {
+                               duk__romptr_high = (const void *) *ptrs;
+                       }
+                       if (*ptrs < duk__romptr_low) {
+                               duk__romptr_low = (const void *) *ptrs;
+                       }
+                       ptrs++;
+               }
+               fprintf(stderr, "romptrs: low=%p high=%p\n",
+                       (const void *) duk__romptr_low, (const void *) 
duk__romptr_high);
+               fflush(stderr);
+       }
+#endif
+}
+
+void ajsheap_free(void) {
+       if (ajsheap_ram != NULL) {
+               free(ajsheap_ram);
+               ajsheap_ram = NULL;
+       }
+}
+
+/* AjsHeap.dump(), allows Ecmascript code to dump heap status at suitable
+ * points.
+ */
+duk_ret_t ajsheap_dump_binding(duk_context *ctx) {
+       AJS_HeapDump();
+       fflush(stdout);
+       return 0;
+}
+
+void ajsheap_dump(void) {
+       AJS_HeapDump();
+       fflush(stdout);
+}
+
+void ajsheap_register(duk_context *ctx) {
+       duk_push_object(ctx);
+       duk_push_c_function(ctx, ajsheap_dump_binding, 0);
+       duk_put_prop_string(ctx, -2, "dump");
+       duk_put_global_string(ctx, "AjsHeap");
+}
+
+/*
+ *  Wrapped ajs_heap.c alloc functions
+ *
+ *  Used to write an alloc log.
+ */
+
+static FILE *ajsheap_alloc_log = NULL;
+
+static void ajsheap_write_alloc_log(const char *fmt, ...) {
+       va_list ap;
+       char buf[256];
+
+       va_start(ap, fmt);
+       vsnprintf(buf, sizeof(buf), fmt, ap);
+       buf[sizeof(buf) - 1] = (char) 0;
+       va_end(ap);
+
+       if (ajsheap_alloc_log == NULL) {
+               ajsheap_alloc_log = fopen("/tmp/ajduk-alloc-log.txt", "wb");
+               if (ajsheap_alloc_log == NULL) {
+                       fprintf(stderr, "WARNING: failed to write alloc log, 
ignoring\n");
+                       fflush(stderr);
+                       return;
+               }
+       }
+
+       (void) fwrite((const void *) buf, 1, strlen(buf), ajsheap_alloc_log);
+       (void) fflush(ajsheap_alloc_log);
+}
+
+void *ajsheap_alloc_wrapped(void *udata, duk_size_t size) {
+       void *ret = AJS_Alloc(udata, size);
+       if (size > 0 && ret == NULL) {
+               ajsheap_write_alloc_log("A FAIL %ld\n", (long) size);
+       } else if (ret == NULL) {
+               ajsheap_write_alloc_log("A NULL %ld\n", (long) size);
+       } else {
+               ajsheap_write_alloc_log("A %p %ld\n", ret, (long) size);
+       }
+       return ret;
+}
+
+void *ajsheap_realloc_wrapped(void *udata, void *ptr, duk_size_t size) {
+       void *ret = AJS_Realloc(udata, ptr, size);
+       if (size > 0 && ret == NULL) {
+               if (ptr == NULL) {
+                       ajsheap_write_alloc_log("R NULL -1 FAIL %ld\n", (long) 
size);
+               } else {
+                       ajsheap_write_alloc_log("R %p -1 FAIL %ld\n", ptr, 
(long) size);
+               }
+       } else if (ret == NULL) {
+               if (ptr == NULL) {
+                       ajsheap_write_alloc_log("R NULL -1 NULL %ld\n", (long) 
size);
+               } else {
+                       ajsheap_write_alloc_log("R %p -1 NULL %ld\n", ptr, 
(long) size);
+               }
+       } else {
+               if (ptr == NULL) {
+                       ajsheap_write_alloc_log("R NULL -1 %p %ld\n", ret, 
(long) size);
+               } else {
+                       ajsheap_write_alloc_log("R %p -1 %p %ld\n", ptr, ret, 
(long) size);
+               }
+       }
+       return ret;
+}
+
+void ajsheap_free_wrapped(void *udata, void *ptr) {
+       AJS_Free(udata, ptr);
+       if (ptr == NULL) {
+       } else {
+               ajsheap_write_alloc_log("F %p -1\n", ptr);
+       }
+}
+
+/*
+ *  Example pointer compression functions.
+ *
+ *  'base' is chosen so that no non-NULL pointer results in a zero result
+ *  which is reserved for NULL pointers.
+ */
+
+duk_uint16_t ajsheap_enc16(void *ud, void *p) {
+       duk_uint32_t ret;
+       char *base = (char *) ajsheap_ram - 4;
+
+#if defined(DUK__ROMPTR_COMPRESSION)
+       if (p >= duk__romptr_low && p <= duk__romptr_high) {
+               /* The if-condition should be the fastest possible check
+                * for "is 'p' in ROM?".  If pointer is in ROM, we'd like
+                * to compress it quickly.  Here we just scan a ~1K array
+                * which is very bad for performance and for illustration
+                * only.
+                */
+               const void * const * ptrs = duk_rom_compressed_pointers;
+               while (*ptrs) {
+                       if (*ptrs == p) {
+                               ret = DUK__ROMPTR_FIRST + (ptrs - 
duk_rom_compressed_pointers);
+#if 0
+                               fprintf(stderr, "ajsheap_enc16: rom pointer: %p 
-> 0x%04lx\n", (void *) p, (long) ret);
+                               fflush(stderr);
+#endif
+                               return (duk_uint16_t) ret;
+                       }
+                       ptrs++;
+               }
+
+               /* We should really never be here: Duktape should only be
+                * compressing pointers which are in the ROM compressed
+                * pointers list, which are known at 'make dist' time.
+                * We go on, causing a pointer compression error.
+                */
+               fprintf(stderr, "ajsheap_enc16: rom pointer: %p could not be 
compressed, should never happen\n", (void *) p);
+               fflush(stderr);
+       }
+#endif
+
+       /* Userdata is not needed in this case but would be useful if heap
+        * pointer compression were used for multiple heaps.  The userdata
+        * allows the callback to distinguish between heaps and their base
+        * pointers.
+        *
+        * If not needed, the userdata can be left out during compilation
+        * by simply ignoring the userdata argument of the pointer encode
+        * and decode macros.  It is kept here so that any bugs in actually
+        * providing the value inside Duktape are revealed during compilation.
+        */
+       (void) ud;
+#if 1
+       /* Ensure that we always get the heap_udata given in heap creation.
+        * (Useful for Duktape development, not needed for user programs.)
+        */
+       if (ud != (void *) 0xdeadbeef) {
+               fprintf(stderr, "invalid udata for ajsheap_enc16: %p\n", ud);
+               fflush(stderr);
+       }
+#endif
+
+       if (p == NULL) {
+               ret = 0;
+       } else {
+               ret = (duk_uint32_t) (((char *) p - base) >> 2);
+       }
+#if 0
+       printf("ajsheap_enc16: %p -> %u\n", p, (unsigned int) ret);
+#endif
+       if (ret > 0xffffUL) {
+               fprintf(stderr, "Failed to compress pointer: %p (ret was 
%ld)\n", (void *) p, (long) ret);
+               fflush(stderr);
+               abort();
+       }
+#if defined(DUK__ROMPTR_COMPRESSION)
+       if (ret >= DUK__ROMPTR_FIRST) {
+               fprintf(stderr, "Failed to compress pointer, in 16-bit range 
but matches romptr range: %p (ret was %ld)\n", (void *) p, (long) ret);
+               fflush(stderr);
+               abort();
+       }
+#endif
+       return (duk_uint16_t) ret;
+}
+
+void *ajsheap_dec16(void *ud, duk_uint16_t x) {
+       void *ret;
+       char *base = (char *) ajsheap_ram - 4;
+
+#if defined(DUK__ROMPTR_COMPRESSION)
+       if (x >= DUK__ROMPTR_FIRST) {
+               /* This is a blind lookup, could check index validity.
+                * Duktape should never decompress a pointer which would
+                * be out-of-bounds here.
+                */
+               ret = (void *) ajduk__lose_const(duk_rom_compressed_pointers[x 
- DUK__ROMPTR_FIRST]);
+#if 0
+               fprintf(stderr, "ajsheap_dec16: rom pointer: 0x%04lx -> %p\n", 
(long) x, ret);
+               fflush(stderr);
+#endif
+               return ret;
+       }
+#endif
+
+       /* See userdata discussion in ajsheap_enc16(). */
+       (void) ud;
+#if 1
+       /* Ensure that we always get the heap_udata given in heap creation. */
+       if (ud != (void *) 0xdeadbeef) {
+               fprintf(stderr, "invalid udata for ajsheap_dec16: %p\n", ud);
+               fflush(stderr);
+       }
+#endif
+
+       if (x == 0) {
+               ret = NULL;
+       } else {
+               ret = (void *) (base + (((duk_uint32_t) x) << 2));
+       }
+#if 0
+       printf("ajsheap_dec16: %u -> %p\n", (unsigned int) x, ret);
+#endif
+       return ret;
+}
+
+/*
+ *  Simplified example of an external strings strategy where incoming strings
+ *  are written sequentially into a fixed, memory mapped flash area.
+ *
+ *  The example first scans if the string is already in the flash (which may
+ *  happen if the same string is interned multiple times), then adds it to
+ *  flash if there is space.
+ *
+ *  This example is too slow to be used in a real world application: there
+ *  should be e.g. a hash table to quickly check for strings that are already
+ *  present in the string data (similarly to how string interning works in
+ *  Duktape itself).
+ */
+
+static uint8_t ajsheap_strdata[65536];
+static size_t ajsheap_strdata_used = 0;
+
+const void *ajsheap_extstr_check_1(const void *ptr, duk_size_t len) {
+       uint8_t *p, *p_end;
+       uint8_t initial;
+       uint8_t *ret;
+       size_t left;
+
+       (void) safe_print_chars;  /* potentially unused */
+
+       if (len <= 3) {
+               /* It's not worth it to make very small strings external, as
+                * they would take the same space anyway.  Also avoids zero
+                * length degenerate case.
+                */
+               return NULL;
+       }
+
+       /*
+        *  Check if we already have the string.  Be careful to compare for
+        *  NUL terminator too, it is NOT present in 'ptr'.  This algorithm
+        *  is too simplistic and way too slow for actual use.
+        */
+
+       initial = ((const uint8_t *) ptr)[0];
+       for (p = ajsheap_strdata, p_end = p + ajsheap_strdata_used; p != p_end; 
p++) {
+               if (*p != initial) {
+                       continue;
+               }
+               left = (size_t) (p_end - p);
+               if (left >= len + 1 &&
+                   memcmp(p, ptr, len) == 0 &&
+                   p[len] == 0) {
+                       ret = p;
+#if 0
+                       printf("ajsheap_extstr_check_1: ptr=%p, len=%ld ",
+                              (void *) ptr, (long) len);
+                       safe_print_chars((const char *) ptr, len, 0 
/*until_nul*/);
+                       printf(" -> existing %p (used=%ld)\n",
+                              (void *) ret, (long) ajsheap_strdata_used);
+#endif
+                       return ret;
+               }
+       }
+
+       /*
+        *  Not present yet, check if we have space.  Again, be careful to
+        *  ensure there is space for a NUL following the input data.
+        */
+
+       if (ajsheap_strdata_used + len + 1 > sizeof(ajsheap_strdata)) {
+#if 0
+               printf("ajsheap_extstr_check_1: ptr=%p, len=%ld ", (void *) 
ptr, (long) len);
+               safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);
+               printf(" -> no space (used=%ld)\n", (long) 
ajsheap_strdata_used);
+#endif
+               return NULL;
+       }
+
+       /*
+        *  There is space, add the string to our collection, being careful
+        *  to append the NUL.
+        */
+
+       ret = ajsheap_strdata + ajsheap_strdata_used;
+       memcpy(ret, ptr, len);
+       ret[len] = (uint8_t) 0;
+       ajsheap_strdata_used += len + 1;
+
+#if 0
+       printf("ajsheap_extstr_check_1: ptr=%p, len=%ld -> ", (void *) ptr, 
(long) len);
+       safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);
+       printf(" -> %p (used=%ld)\n", (void *) ret, (long) 
ajsheap_strdata_used);
+#endif
+       return (const void *) ret;
+}
+
+void ajsheap_extstr_free_1(const void *ptr) {
+       (void) ptr;
+#if 0
+       printf("ajsheap_extstr_free_1: freeing extstr %p -> ", ptr);
+       safe_print_chars((const char *) ptr, DUK_SIZE_MAX, 1 /*until_nul*/);
+       printf("\n");
+#endif
+}
+
+/*
+ *  Simplified example of an external strings strategy where a set of strings
+ *  is gathered during application compile time and baked into the application
+ *  binary.
+ *
+ *  Duktape built-in strings are available from duk_build_meta.json, see
+ *  util/duk_meta_to_strarray.py.  There may also be a lot of application
+ *  specific strings, e.g. those used by application specific APIs.  These
+ *  must be gathered through some other means, see e.g. util/scan_strings.py.
+ */
+
+static const char *strdata_duk_builtin_strings[] = {
+       /*
+        *  These strings are from util/duk_meta_to_strarray.py
+        */
+
+       "Logger",
+       "Thread",
+       "Pointer",
+       "Buffer",
+       "DecEnv",
+       "ObjEnv",
+       "",
+       "global",
+       "Arguments",
+       "JSON",
+       "Math",
+       "Error",
+       "RegExp",
+       "Date",
+       "Number",
+       "Boolean",
+       "String",
+       "Array",
+       "Function",
+       "Object",
+       "Null",
+       "Undefined",
+       "{_func:true}",
+       "{\x22" "_func\x22" ":true}",
+       "{\x22" "_ninf\x22" ":true}",
+       "{\x22" "_inf\x22" ":true}",
+       "{\x22" "_nan\x22" ":true}",
+       "{\x22" "_undef\x22" ":true}",
+       "toLogString",
+       "clog",
+       "l",
+       "n",
+       "fatal",
+       "error",
+       "warn",
+       "debug",
+       "trace",
+       "raw",
+       "fmt",
+       "current",
+       "resume",
+       "compact",
+       "jc",
+       "jx",
+       "base64",
+       "hex",
+       "dec",
+       "enc",
+       "fin",
+       "gc",
+       "act",
+       "info",
+       "version",
+       "env",
+       "modLoaded",
+       "modSearch",
+       "errThrow",
+       "errCreate",
+       "compile",
+       "\xff" "Regbase",
+       "\xff" "Thread",
+       "\xff" "Handler",
+       "\xff" "Finalizer",
+       "\xff" "Callee",
+       "\xff" "Map",
+       "\xff" "Args",
+       "\xff" "This",
+       "\xff" "Pc2line",
+       "\xff" "Source",
+       "\xff" "Varenv",
+       "\xff" "Lexenv",
+       "\xff" "Varmap",
+       "\xff" "Formals",
+       "\xff" "Bytecode",
+       "\xff" "Next",
+       "\xff" "Target",
+       "\xff" "Value",
+       "pointer",
+       "buffer",
+       "\xff" "Tracedata",
+       "lineNumber",
+       "fileName",
+       "pc",
+       "stack",
+       "ThrowTypeError",
+       "Duktape",
+       "id",
+       "require",
+       "__proto__",
+       "setPrototypeOf",
+       "ownKeys",
+       "enumerate",
+       "deleteProperty",
+       "has",
+       "Proxy",
+       "callee",
+       "Invalid Date",
+       "[...]",
+       "\x0a" "\x09",
+       " ",
+       ",",
+       "-0",
+       "+0",
+       "0",
+       "-Infinity",
+       "+Infinity",
+       "Infinity",
+       "object",
+       "string",
+       "number",
+       "boolean",
+       "undefined",
+       "stringify",
+       "tan",
+       "sqrt",
+       "sin",
+       "round",
+       "random",
+       "pow",
+       "min",
+       "max",
+       "log",
+       "floor",
+       "exp",
+       "cos",
+       "ceil",
+       "atan2",
+       "atan",
+       "asin",
+       "acos",
+       "abs",
+       "SQRT2",
+       "SQRT1_2",
+       "PI",
+       "LOG10E",
+       "LOG2E",
+       "LN2",
+       "LN10",
+       "E",
+       "message",
+       "name",
+       "input",
+       "index",
+       "(?:)",
+       "lastIndex",
+       "multiline",
+       "ignoreCase",
+       "source",
+       "test",
+       "exec",
+       "toGMTString",
+       "setYear",
+       "getYear",
+       "toJSON",
+       "toISOString",
+       "toUTCString",
+       "setUTCFullYear",
+       "setFullYear",
+       "setUTCMonth",
+       "setMonth",
+       "setUTCDate",
+       "setDate",
+       "setUTCHours",
+       "setHours",
+       "setUTCMinutes",
+       "setMinutes",
+       "setUTCSeconds",
+       "setSeconds",
+       "setUTCMilliseconds",
+       "setMilliseconds",
+       "setTime",
+       "getTimezoneOffset",
+       "getUTCMilliseconds",
+       "getMilliseconds",
+       "getUTCSeconds",
+       "getSeconds",
+       "getUTCMinutes",
+       "getMinutes",
+       "getUTCHours",
+       "getHours",
+       "getUTCDay",
+       "getDay",
+       "getUTCDate",
+       "getDate",
+       "getUTCMonth",
+       "getMonth",
+       "getUTCFullYear",
+       "getFullYear",
+       "getTime",
+       "toLocaleTimeString",
+       "toLocaleDateString",
+       "toTimeString",
+       "toDateString",
+       "now",
+       "UTC",
+       "parse",
+       "toPrecision",
+       "toExponential",
+       "toFixed",
+       "POSITIVE_INFINITY",
+       "NEGATIVE_INFINITY",
+       "NaN",
+       "MIN_VALUE",
+       "MAX_VALUE",
+       "substr",
+       "trim",
+       "toLocaleUpperCase",
+       "toUpperCase",
+       "toLocaleLowerCase",
+       "toLowerCase",
+       "substring",
+       "split",
+       "search",
+       "replace",
+       "match",
+       "localeCompare",
+       "charCodeAt",
+       "charAt",
+       "fromCharCode",
+       "reduceRight",
+       "reduce",
+       "filter",
+       "map",
+       "forEach",
+       "some",
+       "every",
+       "lastIndexOf",
+       "indexOf",
+       "unshift",
+       "splice",
+       "sort",
+       "slice",
+       "shift",
+       "reverse",
+       "push",
+       "pop",
+       "join",
+       "concat",
+       "isArray",
+       "arguments",
+       "caller",
+       "bind",
+       "call",
+       "apply",
+       "propertyIsEnumerable",
+       "isPrototypeOf",
+       "hasOwnProperty",
+       "valueOf",
+       "toLocaleString",
+       "toString",
+       "constructor",
+       "set",
+       "get",
+       "enumerable",
+       "configurable",
+       "writable",
+       "value",
+       "keys",
+       "isExtensible",
+       "isFrozen",
+       "isSealed",
+       "preventExtensions",
+       "freeze",
+       "seal",
+       "defineProperties",
+       "defineProperty",
+       "create",
+       "getOwnPropertyNames",
+       "getOwnPropertyDescriptor",
+       "getPrototypeOf",
+       "prototype",
+       "length",
+       "alert",
+       "print",
+       "unescape",
+       "escape",
+       "encodeURIComponent",
+       "encodeURI",
+       "decodeURIComponent",
+       "decodeURI",
+       "isFinite",
+       "isNaN",
+       "parseFloat",
+       "parseInt",
+       "eval",
+       "URIError",
+       "TypeError",
+       "SyntaxError",
+       "ReferenceError",
+       "RangeError",
+       "EvalError",
+       "break",
+       "case",
+       "catch",
+       "continue",
+       "debugger",
+       "default",
+       "delete",
+       "do",
+       "else",
+       "finally",
+       "for",
+       "function",
+       "if",
+       "in",
+       "instanceof",
+       "new",
+       "return",
+       "switch",
+       "this",
+       "throw",
+       "try",
+       "typeof",
+       "var",
+       "void",
+       "while",
+       "with",
+       "class",
+       "const",
+       "enum",
+       "export",
+       "extends",
+       "import",
+       "super",
+       "null",
+       "true",
+       "false",
+       "implements",
+       "interface",
+       "let",
+       "package",
+       "private",
+       "protected",
+       "public",
+       "static",
+       "yield",
+
+       /*
+        *  These strings are manually added, and would be gathered in some
+        *  application specific manner.
+        */
+
+       "foo",
+       "bar",
+       "quux",
+       "enableFrob",
+       "disableFrob"
+       /* ... */
+};
+
+const void *ajsheap_extstr_check_2(const void *ptr, duk_size_t len) {
+       int i, n;
+
+       (void) safe_print_chars;  /* potentially unused */
+
+       /* Linear scan.  An actual implementation would need some acceleration
+        * structure, e.g. select a sublist based on first character.
+        *
+        * NOTE: input string (behind 'ptr' with 'len' bytes) DOES NOT have a
+        * trailing NUL character.  Any strings returned from this function
+        * MUST have a trailing NUL character.
+        */
+
+       n = (int) (sizeof(strdata_duk_builtin_strings) / sizeof(const char *));
+       for (i = 0; i < n; i++) {
+               const char *str;
+
+               str = strdata_duk_builtin_strings[i];
+               if (strlen(str) == len && memcmp(ptr, (const void *) str, len) 
== 0) {
+#if 0
+                       printf("ajsheap_extstr_check_2: ptr=%p, len=%ld ",
+                              (void *) ptr, (long) len);
+                       safe_print_chars((const char *) ptr, len, 0 
/*until_nul*/);
+                       printf(" -> constant string index %ld\n", (long) i);
+#endif
+                       return (void *) 
ajduk__lose_const(strdata_duk_builtin_strings[i]);
+               }
+       }
+
+#if 0
+       printf("ajsheap_extstr_check_2: ptr=%p, len=%ld ",
+              (void *) ptr, (long) len);
+       safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);
+       printf(" -> not found\n");
+#endif
+       return NULL;
+}
+
+void ajsheap_extstr_free_2(const void *ptr) {
+       (void) ptr;
+#if 0
+       printf("ajsheap_extstr_free_2: freeing extstr %p -> ", ptr);
+       safe_print_chars((const char *) ptr, DUK_SIZE_MAX, 1 /*until_nul*/);
+       printf("\n");
+#endif
+}
+
+/*
+ *  External strings strategy intended for valgrind testing: external strings
+ *  are allocated using malloc()/free() so that valgrind can be used to ensure
+ *  that strings are e.g. freed exactly once.
+ */
+
+const void *ajsheap_extstr_check_3(const void *ptr, duk_size_t len) {
+       duk_uint8_t *ret;
+
+       (void) safe_print_chars;  /* potentially unused */
+
+       ret = malloc((size_t) len + 1);
+       if (ret == NULL) {
+#if 0
+               printf("ajsheap_extstr_check_3: ptr=%p, len=%ld ",
+                      (void *) ptr, (long) len);
+               safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);
+               printf(" -> malloc failed, return NULL\n");
+#endif
+               return (const void *) NULL;
+       }
+
+       if (len > 0) {
+               memcpy((void *) ret, ptr, (size_t) len);
+       }
+       ret[len] = (duk_uint8_t) 0;
+
+#if 0
+       printf("ajsheap_extstr_check_3: ptr=%p, len=%ld ",
+              (void *) ptr, (long) len);
+       safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);
+       printf(" -> %p\n", (void *) ret);
+#endif
+       return (const void *) ret;
+}
+
+void ajsheap_extstr_free_3(const void *ptr) {
+       (void) ptr;
+#if 0
+       printf("ajsheap_extstr_free_3: freeing extstr %p -> ", ptr);
+       safe_print_chars((const char *) ptr, DUK_SIZE_MAX, 1 /*until_nul*/);
+       printf("\n");
+#endif
+       free((void *) ajduk__lose_const(ptr));
+}
+
+/*
+ *  Execution timeout example
+ */
+
+#define  AJSHEAP_EXEC_TIMEOUT  5  /* seconds */
+
+static time_t curr_pcall_start = 0;
+static long exec_timeout_check_counter = 0;
+
+void ajsheap_start_exec_timeout(void) {
+       curr_pcall_start = time(NULL);
+}
+
+void ajsheap_clear_exec_timeout(void) {
+       curr_pcall_start = 0;
+}
+
+duk_bool_t ajsheap_exec_timeout_check(void *udata) {
+       time_t now = time(NULL);
+       time_t diff = now - curr_pcall_start;
+
+       (void) udata;  /* not needed */
+
+       exec_timeout_check_counter++;
+#if 0
+       printf("exec timeout check %ld: now=%ld, start=%ld, diff=%ld\n",
+              (long) exec_timeout_check_counter, (long) now, (long) 
curr_pcall_start, (long) diff);
+       fflush(stdout);
+#endif
+
+       if (curr_pcall_start == 0) {
+               /* protected call not yet running */
+               return 0;
+       }
+       if (diff > AJSHEAP_EXEC_TIMEOUT) {
+               return 1;
+       }
+       return 0;
+}
+
+#else  /* DUK_CMDLINE_AJSHEAP */
+
+int ajs_dummy = 0;  /* to avoid empty source file */
+
+#endif  /* DUK_CMDLINE_AJSHEAP */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/README.rst
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/README.rst
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/README.rst
new file mode 100644
index 0000000..98b53d2
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/README.rst
@@ -0,0 +1,8 @@
+Codepage conversion example
+===========================
+
+Example of how to convert an 8-bit input string (e.g. ISO-8859-1 or Windows
+codepage 1252) into CESU-8 without using an external library like iconv.
+
+This is useful e.g. when compiling non-UTF-8 source code which cannot be
+converted to UTF-8 (CESU-8) at build time.

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/duk_codepage_conv.c
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/duk_codepage_conv.c
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/duk_codepage_conv.c
new file mode 100644
index 0000000..932e9a6
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/duk_codepage_conv.c
@@ -0,0 +1,54 @@
+/*
+ *  Convert an 8-bit input string (e.g. ISO-8859-1) into CESU-8.
+ *  Calling code supplies the "code page" as a 256-entry array of
+ *  codepoints for the conversion.
+ *
+ *  This is useful when input data is in non-UTF-8 format and must
+ *  be converted at runtime, e.g. when compiling non-UTF-8 source
+ *  code.  Another alternative is to use e.g. iconv.
+ */
+
+#include "duktape.h"
+
+/* Decode an 8-bit string using 'codepage' into Unicode codepoints and
+ * re-encode into CESU-8.  Codepage argument must point to a 256-entry
+ * table.  Only supports BMP (codepoints U+0000 to U+FFFF).
+ */
+void duk_decode_string_codepage(duk_context *ctx, const char *str, size_t len, 
unsigned int *codepage) {
+       unsigned char *tmp;
+       size_t tmplen, i;
+       unsigned char *p;
+       unsigned int cp;
+
+       tmplen = 3 * len;  /* max expansion is 1 input byte -> 3 output bytes */
+       if (tmplen / 3 != len) {
+               /* Temporary buffer length wraps. */
+               duk_error(ctx, DUK_ERR_RANGE_ERROR, "input string too long");
+               return;
+       }
+
+       tmp = (unsigned char *) duk_push_fixed_buffer(ctx, tmplen);
+
+       for (i = 0, p = tmp; i < len; i++) {
+               cp = codepage[((unsigned char *) str)[i]] & 0xffffUL;
+               if (cp < 0x80UL) {
+                       *p++ = (unsigned char) cp;
+               } else if (cp < 0x800UL) {
+                       *p++ = (unsigned char) (0xc0 + ((cp >> 6) & 0x1f));
+                       *p++ = (unsigned char) (0x80 + (cp & 0x3f));
+               } else {
+                       /* In CESU-8 all codepoints in [0x0000,0xFFFF] are
+                        * allowed, including surrogates.
+                        */
+                       *p++ = (unsigned char) (0xe0 + ((cp >> 12) & 0x0f));
+                       *p++ = (unsigned char) (0x80 + ((cp >> 6) & 0x3f));
+                       *p++ = (unsigned char) (0x80 + (cp & 0x3f));
+               }
+       }
+
+       duk_push_lstring(ctx, (const char *) tmp, (duk_size_t) (p - tmp));
+
+       /* [ ... tmp res ] */
+
+       duk_remove(ctx, -2);
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/duk_codepage_conv.h
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/duk_codepage_conv.h
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/duk_codepage_conv.h
new file mode 100644
index 0000000..d2705a0
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/duk_codepage_conv.h
@@ -0,0 +1,8 @@
+#ifndef DUK_CODEPAGE_CONV_H_INCLUDED
+#define DUK_CODEPAGE_CONV_H_INCLUDED
+
+#include "duktape.h"
+
+void duk_decode_string_codepage(duk_context *ctx, const char *str, size_t len, 
unsigned int *codepage);
+
+#endif  /* DUK_CODEPAGE_CONV_H_INCLUDED */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/test.c
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/test.c
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/test.c
new file mode 100644
index 0000000..c34299a
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/codepage-conv/test.c
@@ -0,0 +1,286 @@
+#include "duktape.h"
+#include "duk_codepage_conv.h"
+
+/* http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT */
+unsigned int cp1252[256] = {
+       (unsigned int) 0x0000,
+       (unsigned int) 0x0001,
+       (unsigned int) 0x0002,
+       (unsigned int) 0x0003,
+       (unsigned int) 0x0004,
+       (unsigned int) 0x0005,
+       (unsigned int) 0x0006,
+       (unsigned int) 0x0007,
+       (unsigned int) 0x0008,
+       (unsigned int) 0x0009,
+       (unsigned int) 0x000A,
+       (unsigned int) 0x000B,
+       (unsigned int) 0x000C,
+       (unsigned int) 0x000D,
+       (unsigned int) 0x000E,
+       (unsigned int) 0x000F,
+       (unsigned int) 0x0010,
+       (unsigned int) 0x0011,
+       (unsigned int) 0x0012,
+       (unsigned int) 0x0013,
+       (unsigned int) 0x0014,
+       (unsigned int) 0x0015,
+       (unsigned int) 0x0016,
+       (unsigned int) 0x0017,
+       (unsigned int) 0x0018,
+       (unsigned int) 0x0019,
+       (unsigned int) 0x001A,
+       (unsigned int) 0x001B,
+       (unsigned int) 0x001C,
+       (unsigned int) 0x001D,
+       (unsigned int) 0x001E,
+       (unsigned int) 0x001F,
+       (unsigned int) 0x0020,
+       (unsigned int) 0x0021,
+       (unsigned int) 0x0022,
+       (unsigned int) 0x0023,
+       (unsigned int) 0x0024,
+       (unsigned int) 0x0025,
+       (unsigned int) 0x0026,
+       (unsigned int) 0x0027,
+       (unsigned int) 0x0028,
+       (unsigned int) 0x0029,
+       (unsigned int) 0x002A,
+       (unsigned int) 0x002B,
+       (unsigned int) 0x002C,
+       (unsigned int) 0x002D,
+       (unsigned int) 0x002E,
+       (unsigned int) 0x002F,
+       (unsigned int) 0x0030,
+       (unsigned int) 0x0031,
+       (unsigned int) 0x0032,
+       (unsigned int) 0x0033,
+       (unsigned int) 0x0034,
+       (unsigned int) 0x0035,
+       (unsigned int) 0x0036,
+       (unsigned int) 0x0037,
+       (unsigned int) 0x0038,
+       (unsigned int) 0x0039,
+       (unsigned int) 0x003A,
+       (unsigned int) 0x003B,
+       (unsigned int) 0x003C,
+       (unsigned int) 0x003D,
+       (unsigned int) 0x003E,
+       (unsigned int) 0x003F,
+       (unsigned int) 0x0040,
+       (unsigned int) 0x0041,
+       (unsigned int) 0x0042,
+       (unsigned int) 0x0043,
+       (unsigned int) 0x0044,
+       (unsigned int) 0x0045,
+       (unsigned int) 0x0046,
+       (unsigned int) 0x0047,
+       (unsigned int) 0x0048,
+       (unsigned int) 0x0049,
+       (unsigned int) 0x004A,
+       (unsigned int) 0x004B,
+       (unsigned int) 0x004C,
+       (unsigned int) 0x004D,
+       (unsigned int) 0x004E,
+       (unsigned int) 0x004F,
+       (unsigned int) 0x0050,
+       (unsigned int) 0x0051,
+       (unsigned int) 0x0052,
+       (unsigned int) 0x0053,
+       (unsigned int) 0x0054,
+       (unsigned int) 0x0055,
+       (unsigned int) 0x0056,
+       (unsigned int) 0x0057,
+       (unsigned int) 0x0058,
+       (unsigned int) 0x0059,
+       (unsigned int) 0x005A,
+       (unsigned int) 0x005B,
+       (unsigned int) 0x005C,
+       (unsigned int) 0x005D,
+       (unsigned int) 0x005E,
+       (unsigned int) 0x005F,
+       (unsigned int) 0x0060,
+       (unsigned int) 0x0061,
+       (unsigned int) 0x0062,
+       (unsigned int) 0x0063,
+       (unsigned int) 0x0064,
+       (unsigned int) 0x0065,
+       (unsigned int) 0x0066,
+       (unsigned int) 0x0067,
+       (unsigned int) 0x0068,
+       (unsigned int) 0x0069,
+       (unsigned int) 0x006A,
+       (unsigned int) 0x006B,
+       (unsigned int) 0x006C,
+       (unsigned int) 0x006D,
+       (unsigned int) 0x006E,
+       (unsigned int) 0x006F,
+       (unsigned int) 0x0070,
+       (unsigned int) 0x0071,
+       (unsigned int) 0x0072,
+       (unsigned int) 0x0073,
+       (unsigned int) 0x0074,
+       (unsigned int) 0x0075,
+       (unsigned int) 0x0076,
+       (unsigned int) 0x0077,
+       (unsigned int) 0x0078,
+       (unsigned int) 0x0079,
+       (unsigned int) 0x007A,
+       (unsigned int) 0x007B,
+       (unsigned int) 0x007C,
+       (unsigned int) 0x007D,
+       (unsigned int) 0x007E,
+       (unsigned int) 0x007F,
+       (unsigned int) 0x20AC,
+       (unsigned int) 0xFFFD,  /* undefined */
+       (unsigned int) 0x201A,
+       (unsigned int) 0x0192,
+       (unsigned int) 0x201E,
+       (unsigned int) 0x2026,
+       (unsigned int) 0x2020,
+       (unsigned int) 0x2021,
+       (unsigned int) 0x02C6,
+       (unsigned int) 0x2030,
+       (unsigned int) 0x0160,
+       (unsigned int) 0x2039,
+       (unsigned int) 0x0152,
+       (unsigned int) 0xFFFD,  /* undefined */
+       (unsigned int) 0x017D,
+       (unsigned int) 0xFFFD,  /* undefined */
+       (unsigned int) 0xFFFD,  /* undefined */
+       (unsigned int) 0x2018,
+       (unsigned int) 0x2019,
+       (unsigned int) 0x201C,
+       (unsigned int) 0x201D,
+       (unsigned int) 0x2022,
+       (unsigned int) 0x2013,
+       (unsigned int) 0x2014,
+       (unsigned int) 0x02DC,
+       (unsigned int) 0x2122,
+       (unsigned int) 0x0161,
+       (unsigned int) 0x203A,
+       (unsigned int) 0x0153,
+       (unsigned int) 0xFFFD,  /* undefined */
+       (unsigned int) 0x017E,
+       (unsigned int) 0x0178,
+       (unsigned int) 0x00A0,
+       (unsigned int) 0x00A1,
+       (unsigned int) 0x00A2,
+       (unsigned int) 0x00A3,
+       (unsigned int) 0x00A4,
+       (unsigned int) 0x00A5,
+       (unsigned int) 0x00A6,
+       (unsigned int) 0x00A7,
+       (unsigned int) 0x00A8,
+       (unsigned int) 0x00A9,
+       (unsigned int) 0x00AA,
+       (unsigned int) 0x00AB,
+       (unsigned int) 0x00AC,
+       (unsigned int) 0x00AD,
+       (unsigned int) 0x00AE,
+       (unsigned int) 0x00AF,
+       (unsigned int) 0x00B0,
+       (unsigned int) 0x00B1,
+       (unsigned int) 0x00B2,
+       (unsigned int) 0x00B3,
+       (unsigned int) 0x00B4,
+       (unsigned int) 0x00B5,
+       (unsigned int) 0x00B6,
+       (unsigned int) 0x00B7,
+       (unsigned int) 0x00B8,
+       (unsigned int) 0x00B9,
+       (unsigned int) 0x00BA,
+       (unsigned int) 0x00BB,
+       (unsigned int) 0x00BC,
+       (unsigned int) 0x00BD,
+       (unsigned int) 0x00BE,
+       (unsigned int) 0x00BF,
+       (unsigned int) 0x00C0,
+       (unsigned int) 0x00C1,
+       (unsigned int) 0x00C2,
+       (unsigned int) 0x00C3,
+       (unsigned int) 0x00C4,
+       (unsigned int) 0x00C5,
+       (unsigned int) 0x00C6,
+       (unsigned int) 0x00C7,
+       (unsigned int) 0x00C8,
+       (unsigned int) 0x00C9,
+       (unsigned int) 0x00CA,
+       (unsigned int) 0x00CB,
+       (unsigned int) 0x00CC,
+       (unsigned int) 0x00CD,
+       (unsigned int) 0x00CE,
+       (unsigned int) 0x00CF,
+       (unsigned int) 0x00D0,
+       (unsigned int) 0x00D1,
+       (unsigned int) 0x00D2,
+       (unsigned int) 0x00D3,
+       (unsigned int) 0x00D4,
+       (unsigned int) 0x00D5,
+       (unsigned int) 0x00D6,
+       (unsigned int) 0x00D7,
+       (unsigned int) 0x00D8,
+       (unsigned int) 0x00D9,
+       (unsigned int) 0x00DA,
+       (unsigned int) 0x00DB,
+       (unsigned int) 0x00DC,
+       (unsigned int) 0x00DD,
+       (unsigned int) 0x00DE,
+       (unsigned int) 0x00DF,
+       (unsigned int) 0x00E0,
+       (unsigned int) 0x00E1,
+       (unsigned int) 0x00E2,
+       (unsigned int) 0x00E3,
+       (unsigned int) 0x00E4,
+       (unsigned int) 0x00E5,
+       (unsigned int) 0x00E6,
+       (unsigned int) 0x00E7,
+       (unsigned int) 0x00E8,
+       (unsigned int) 0x00E9,
+       (unsigned int) 0x00EA,
+       (unsigned int) 0x00EB,
+       (unsigned int) 0x00EC,
+       (unsigned int) 0x00ED,
+       (unsigned int) 0x00EE,
+       (unsigned int) 0x00EF,
+       (unsigned int) 0x00F0,
+       (unsigned int) 0x00F1,
+       (unsigned int) 0x00F2,
+       (unsigned int) 0x00F3,
+       (unsigned int) 0x00F4,
+       (unsigned int) 0x00F5,
+       (unsigned int) 0x00F6,
+       (unsigned int) 0x00F7,
+       (unsigned int) 0x00F8,
+       (unsigned int) 0x00F9,
+       (unsigned int) 0x00FA,
+       (unsigned int) 0x00FB,
+       (unsigned int) 0x00FC,
+       (unsigned int) 0x00FD,
+       (unsigned int) 0x00FE,
+       (unsigned int) 0x00FF
+};
+
+/* Exercise all 3 byte lengths: any ASCII character is 1 byte, 0xFC maps to
+ * U+00FC which is 2 bytes, and 0x80 maps to U+20AC which is 3 bytes.
+ */
+static const char *example_source = "print('Hello w\xfcrld - \x80');";
+
+/* Example: compile and run test source encoded in Windows codepage 1252. */
+int main(int argc, char *argv[]) {
+       duk_context *ctx;
+
+       (void) argc; (void) argv;
+
+       ctx = duk_create_heap_default();
+       if (!ctx) {
+               printf("Failed to create Duktape heap.\n");
+               return 1;
+       }
+
+       duk_decode_string_codepage(ctx, example_source, strlen(example_source), 
cp1252);
+       duk_eval_noresult(ctx);
+
+       duk_destroy_heap(ctx);
+       return 0;
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/README.rst
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/README.rst
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/README.rst
new file mode 100644
index 0000000..f147522
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/README.rst
@@ -0,0 +1,10 @@
+=====================
+Coffeescript examples
+=====================
+
+A few tests to see how CoffeeScript works with Duktape.  Just convert the
+Coffeescript files to Javascript with the ``Makefile.coffee`` in the
+distributable, or manually::
+
+  $ coffee -c hello.coffee
+  $ cat hello.js

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/globals.coffee
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/globals.coffee
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/globals.coffee
new file mode 100644
index 0000000..25773cd
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/globals.coffee
@@ -0,0 +1,7 @@
+
+print '*** All globals'
+print(name) for name in Object.getOwnPropertyNames(this)
+
+print '*** Globals with a short name (<= 8 chars)'
+print(name) for name in Object.getOwnPropertyNames(this) when name.length <= 8
+

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/hello.coffee
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/hello.coffee
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/hello.coffee
new file mode 100644
index 0000000..088ed8d
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/hello.coffee
@@ -0,0 +1,2 @@
+print 'Hello world!'
+print 'version: ' + Duktape.version

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/a9485aeb/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/mandel.coffee
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/mandel.coffee
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/mandel.coffee
new file mode 100644
index 0000000..8e3e170
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/examples/coffee/mandel.coffee
@@ -0,0 +1,28 @@
+mandel = (x0, y0, x1, y1, w, h, maxiter) ->
+  [dx, dy] = [(x1 - x0) / w, (y1 - y0) / h]
+  res = []
+
+  y = y0
+  for yc in [0..h-1]
+    x = x0
+    for xc in [0..w-1]
+      [xx, yy] = [x, y]
+      c = '*'
+      for i in [0..maxiter-1]
+        # (xx+i*yy)^2 + (x+i*y) = xx^2 + i*2*xx*yy - yy^2 + x + i*y
+        # = (xx^2 - yy^2 + x) + i*(2*xx*yy + y)
+        [xx2, yy2] = [xx*xx, yy*yy]
+        if xx2 + yy2 >= 4.0
+          c = '.'
+          break
+        [xx, yy] = [xx2 - yy2 + x, 2*xx*yy + y]
+      res.push(c)
+      x += dx
+    res.push('\n')
+    y += dy
+
+  print(res.join(''))
+  return
+
+mandel(-2, 2, 2, -2, 200, 100, 1000)
+

Reply via email to