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/config/genconfig.py
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/config/genconfig.py 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/config/genconfig.py
new file mode 100644
index 0000000..9c99648
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/config/genconfig.py
@@ -0,0 +1,1537 @@
+#!/usr/bin/env python2
+#
+#  Process Duktape option metadata and produce various useful outputs:
+#
+#    - duk_config.h with specific or autodetected platform, compiler, and
+#      architecture; forced options; sanity checks; etc
+#    - option documentation for Duktape 1.x feature options (DUK_OPT_xxx)
+#    - option documentation for Duktape 1.x/2.x config options (DUK_USE_xxx)
+#
+#  Genconfig tries to build all outputs based on modular metadata, so that
+#  managing a large number of config options (which is hard to avoid given
+#  the wide range of targets Duktape supports) remains maintainable.
+#
+#  Genconfig does *not* try to support all exotic platforms out there.
+#  Instead, the goal is to allow the metadata to be extended, or to provide
+#  a reasonable starting point for manual duk_config.h tweaking.
+#
+#  For Duktape 1.3 release the main goal was to autogenerate a Duktape 1.2
+#  compatible "autodetect" header from legacy snippets, with other outputs
+#  being experimental.  For Duktape 1.4 duk_config.h is always created from
+#  modular sources.
+#
+
+import os
+import sys
+import re
+import json
+import yaml
+import optparse
+import tarfile
+import tempfile
+import atexit
+import shutil
+try:
+       from StringIO import StringIO
+except ImportError:
+       from io import StringIO
+
+#
+#  Globals holding scanned metadata, helper snippets, etc
+#
+
+# Metadata to scan from config files.
+use_defs = None
+use_defs_list = None
+opt_defs = None
+opt_defs_list = None
+use_tags = None
+use_tags_list = None
+tags_meta = None
+required_use_meta_keys = [
+       'define',
+       'introduced',
+       'default',
+       'tags',
+       'description'
+]
+allowed_use_meta_keys = [
+       'define',
+       'feature_enables',
+       'feature_disables',
+       'feature_snippet',
+       'feature_no_default',
+       'related_feature_defines',
+       'introduced',
+       'deprecated',
+       'removed',
+       'unused',
+       'requires',
+       'conflicts',
+       'related',
+       'default',
+       'tags',
+       'description',
+]
+required_opt_meta_keys = [
+       'define',
+       'introduced',
+       'tags',
+       'description'
+]
+allowed_opt_meta_keys = [
+       'define',
+       'introduced',
+       'deprecated',
+       'removed',
+       'unused',
+       'requires',
+       'conflicts',
+       'related',
+       'tags',
+       'description'
+]
+
+# Preferred tag order for option documentation.
+doc_tag_order = [
+       'portability',
+       'memory',
+       'lowmemory',
+       'ecmascript',
+       'execution',
+       'debugger',
+       'debug',
+       'development'
+]
+
+# Preferred tag order for generated C header files.
+header_tag_order = doc_tag_order
+
+# Helper headers snippets.
+helper_snippets = None
+
+# Assume these provides come from outside.
+assumed_provides = {
+       'DUK_SINGLE_FILE': True,         # compiling Duktape from a single 
source file (duktape.c) version
+       'DUK_COMPILING_DUKTAPE': True,   # compiling Duktape (not user 
application)
+       'DUK_CONFIG_H_INCLUDED': True,   # artifact, include guard
+}
+
+# Platform files must provide at least these (additional checks
+# in validate_platform_file()).  Fill-ins provide missing optionals.
+platform_required_provides = [
+       'DUK_USE_OS_STRING'  # must be #define'd
+]
+
+# Architecture files must provide at least these (additional checks
+# in validate_architecture_file()).  Fill-ins provide missing optionals.
+architecture_required_provides = [
+       'DUK_USE_ARCH_STRING'
+]
+
+# Compiler files must provide at least these (additional checks
+# in validate_compiler_file()).  Fill-ins provide missing optionals.
+compiler_required_provides = [
+       # Compilers need a lot of defines; missing defines are automatically
+       # filled in with defaults (which are mostly compiler independent), so
+       # the requires define list is not very large.
+
+       'DUK_USE_COMPILER_STRING',    # must be #define'd
+       'DUK_USE_BRANCH_HINTS',       # may be #undef'd, as long as provided
+       'DUK_USE_VARIADIC_MACROS',    # may be #undef'd, as long as provided
+       'DUK_USE_UNION_INITIALIZERS'  # may be #undef'd, as long as provided
+]
+
+#
+#  Miscellaneous helpers
+#
+
+def get_auto_delete_tempdir():
+       tmpdir = tempfile.mkdtemp(suffix='-genconfig')
+       def _f(dirname):
+               #print('Deleting temporary directory: %r' % dirname)
+               if os.path.isdir(dirname) and '-genconfig' in dirname:
+                       shutil.rmtree(dirname)
+       atexit.register(_f, tmpdir)
+       return tmpdir
+
+def strip_comments_from_lines(lines):
+       # Not exact but close enough.  Doesn't handle string literals etc,
+       # but these are not a concrete issue for scanning preprocessor
+       # #define references.
+       #
+       # Comment contents are stripped of any DUK_ prefixed text to avoid
+       # incorrect requires/provides detection.  Other comment text is kept;
+       # in particular a "/* redefine */" comment must remain intact here.
+       # (The 'redefine' hack is not actively needed now.)
+       #
+       # Avoid Python 2.6 vs. Python 2.7 argument differences.
+
+       def censor(x):
+               return re.sub(re.compile('DUK_\w+', re.MULTILINE), 'xxx', 
x.group(0))
+
+       tmp = '\n'.join(lines)
+       tmp = re.sub(re.compile('/\*.*?\*/', re.MULTILINE | re.DOTALL), censor, 
tmp)
+       tmp = re.sub(re.compile('//.*?$', re.MULTILINE), censor, tmp)
+       return tmp.split('\n')
+
+# Header snippet representation: lines, provides defines, requires defines.
+re_line_provides = re.compile(r'^#(?:define|undef)\s+(\w+).*$')
+re_line_requires = re.compile(r'(DUK_[A-Z0-9_]+)')  # uppercase only, don't 
match DUK_USE_xxx for example
+class Snippet:
+       lines = None     # lines of text and/or snippets
+       provides = None  # map from define to 'True' for now
+       requires = None  # map from define to 'True' for now
+
+       def __init__(self, lines, provides=None, requires=None, 
autoscan_requires=True, autoscan_provides=True):
+               self.lines = []
+               if not isinstance(lines, list):
+                       raise Exception('Snippet constructor must be a list 
(not e.g. a string): %s' % repr(lines))
+               for line in lines:
+                       if isinstance(line, str):
+                               self.lines.append(line)
+                       elif isinstance(line, unicode):
+                               self.lines.append(line.encode('utf-8'))
+                       else:
+                               raise Exception('invalid line: %r' % line)
+               self.provides = {}
+               if provides is not None:
+                       for k in provides.keys():
+                               self.provides[k] = True
+               self.requires = {}
+               if requires is not None:
+                       for k in requires.keys():
+                               self.requires[k] = True
+
+               stripped_lines = strip_comments_from_lines(lines)
+               # for line in stripped_lines: print(line)
+
+               for line in stripped_lines:
+                       # Careful with order, snippet may self-reference its own
+                       # defines in which case there's no outward dependency.
+                       # (This is not 100% because the order of require/provide
+                       # matters and this is not handled now.)
+                       #
+                       # Also, some snippets may #undef/#define another define 
but
+                       # they don't "provide" the define as such.  Such 
redefinitions
+                       # are marked "/* redefine */" in the snippets.  They're 
best
+                       # avoided (and not currently needed in Duktape 1.4.0).
+
+                       if autoscan_provides:
+                               m = re_line_provides.match(line)
+                               if m is not None and '/* redefine */' not in 
line and \
+                                       len(m.group(1)) > 0 and m.group(1)[-1] 
!= '_':
+                                       # Don't allow e.g. DUK_USE_ which 
results from matching DUK_USE_xxx
+                                       #print('PROVIDES: %r' % m.group(1))
+                                       self.provides[m.group(1)] = True
+                       if autoscan_requires:
+                               matches = re.findall(re_line_requires, line)
+                               for m in matches:
+                                       if len(m) > 0 and m[-1] == '_':
+                                               # Don't allow e.g. DUK_USE_ 
which results from matching DUK_USE_xxx
+                                               pass
+                                       elif m[:7] == 'DUK_OPT':
+                                               # DUK_OPT_xxx always come from 
outside
+                                               pass
+                                       elif m[:7] == 'DUK_USE':
+                                               # DUK_USE_xxx are internal and 
they should not be 'requirements'
+                                               pass
+                                       elif self.provides.has_key(m):
+                                               # Snippet provides it's own 
require; omit
+                                               pass
+                                       else:
+                                               #print('REQUIRES: %r' % m)
+                                               self.requires[m] = True
+
+       def fromFile(cls, filename):
+               lines = []
+               with open(filename, 'rb') as f:
+                       for line in f:
+                               if line[-1] == '\n':
+                                       line = line[:-1]
+                               if line[:8] == '#snippet':
+                                       m = re.match(r'#snippet\s+"(.*?)"', 
line)
+                                       # XXX: better plumbing for lookup path
+                                       sub_fn = 
os.path.normpath(os.path.join(filename, '..', '..', 'header-snippets', 
m.group(1)))
+                                       #print('#snippet ' + sub_fn)
+                                       sn = Snippet.fromFile(sub_fn)
+                                       lines += sn.lines
+                               else:
+                                       lines.append(line)
+               return Snippet(lines, autoscan_requires=True, 
autoscan_provides=True)
+       fromFile = classmethod(fromFile)
+
+       def merge(cls, snippets):
+               ret = Snippet([], [], [])
+               for s in snippets:
+                       ret.lines += s.lines
+                       for k in s.provides.keys():
+                               ret.provides[k] = True
+                       for k in s.requires.keys():
+                               ret.requires[k] = True
+               return ret
+       merge = classmethod(merge)
+
+# Helper for building a text file from individual lines, injected files, etc.
+# Inserted values are converted to Snippets so that their provides/requires
+# information can be tracked.  When non-C outputs are created, these will be
+# bogus but ignored.
+class FileBuilder:
+       vals = None  # snippet list
+       base_dir = None
+       use_cpp_warning = False
+
+       def __init__(self, base_dir=None, use_cpp_warning=False):
+               self.vals = []
+               self.base_dir = base_dir
+               self.use_cpp_warning = use_cpp_warning
+
+       def line(self, line):
+               self.vals.append(Snippet([ line ]))
+
+       def lines(self, lines):
+               if len(lines) > 0 and lines[-1] == '\n':
+                       lines = lines[:-1]  # strip last newline to avoid empty 
line
+               self.vals.append(Snippet(lines.split('\n')))
+
+       def empty(self):
+               self.vals.append(Snippet([ '' ]))
+
+       def rst_heading(self, title, char, doubled=False):
+               tmp = []
+               if doubled:
+                       tmp.append(char * len(title))
+               tmp.append(title)
+               tmp.append(char * len(title))
+               self.vals.append(Snippet(tmp))
+
+       def snippet_relative(self, fn):
+               sn = Snippet.fromFile(os.path.join(self.base_dir, fn))
+               self.vals.append(sn)
+               return sn
+
+       def snippet_absolute(self, fn):
+               sn = Snippet.fromFile(fn)
+               self.vals.append(sn)
+               return sn
+
+       def cpp_error(self, msg):
+               # XXX: assume no newlines etc
+               self.vals.append(Snippet([ '#error %s' % msg ]))
+
+       def cpp_warning(self, msg):
+               # XXX: assume no newlines etc
+               # XXX: support compiler specific warning mechanisms
+               if self.use_cpp_warning:
+                       # C preprocessor '#warning' is often supported
+                       self.vals.append(Snippet([ '#warning %s' % msg ]))
+               else:
+                       self.vals.append(Snippet([ '/* WARNING: %s */' % msg ]))
+
+       def cpp_warning_or_error(self, msg, is_error=True):
+               if is_error:
+                       self.cpp_error(msg)
+               else:
+                       self.cpp_warning(msg)
+
+       def chdr_comment_line(self, msg):
+               self.vals.append(Snippet([ '/* %s */' % msg ]))
+
+       def chdr_block_heading(self, msg):
+               lines = []
+               lines.append('')
+               lines.append('/*')
+               lines.append(' *  ' + msg)
+               lines.append(' */')
+               lines.append('')
+               self.vals.append(Snippet(lines))
+
+       def join(self):
+               tmp = []
+               for line in self.vals:
+                       if not isinstance(line, object):
+                               raise Exception('self.vals must be all 
snippets')
+                       for x in line.lines:  # x is a Snippet
+                               tmp.append(x)
+               return '\n'.join(tmp)
+
+       def fill_dependencies_for_snippets(self, idx_deps):
+               fill_dependencies_for_snippets(self.vals, idx_deps)
+
+# Insert missing define dependencies into index 'idx_deps' repeatedly
+# until no unsatisfied dependencies exist.  This is used to pull in
+# the required DUK_F_xxx helper defines without pulling them all in.
+# The resolution mechanism also ensures dependencies are pulled in the
+# correct order, i.e. DUK_F_xxx helpers may depend on each other (as
+# long as there are no circular dependencies).
+#
+# XXX: this can be simplified a lot
+def fill_dependencies_for_snippets(snippets, idx_deps):
+       # graph[A] = [ B, ... ] <-> B, ... provide something A requires.
+       graph = {}
+       snlist = []
+       resolved = []   # for printing only
+
+       def add(sn):
+               if sn in snlist:
+                       return  # already present
+               snlist.append(sn)
+
+               to_add = []
+
+               for k in sn.requires.keys():
+                       if assumed_provides.has_key(k):
+                               continue
+
+                       found = False
+                       for sn2 in snlist:
+                               if sn2.provides.has_key(k):
+                                       if not graph.has_key(sn):
+                                               graph[sn] = []
+                                       graph[sn].append(sn2)
+                                       found = True  # at least one other node 
provides 'k'
+
+                       if not found:
+                               #print('Resolving %r' % k)
+                               resolved.append(k)
+
+                               # Find a header snippet which provides the 
missing define.
+                               # Some DUK_F_xxx files provide multiple 
defines, so we don't
+                               # necessarily know the snippet filename here.
+
+                               sn_req = None
+                               for sn2 in helper_snippets:
+                                       if sn2.provides.has_key(k):
+                                               sn_req = sn2
+                                               break
+                               if sn_req is None:
+                                       print(repr(sn.lines))
+                                       raise Exception('cannot resolve missing 
require: %r' % k)
+
+                               # Snippet may have further unresolved provides; 
add recursively
+                               to_add.append(sn_req)
+
+                               if not graph.has_key(sn):
+                                       graph[sn] = []
+                               graph[sn].append(sn_req)
+
+               for sn in to_add:
+                       add(sn)
+
+       # Add original snippets.  This fills in the required nodes
+       # recursively.
+       for sn in snippets:
+               add(sn)
+
+       # Figure out fill-ins by looking for snippets not in original
+       # list and without any unserialized dependent nodes.
+       handled = {}
+       for sn in snippets:
+               handled[sn] = True
+       keepgoing = True
+       while keepgoing:
+               keepgoing = False
+               for sn in snlist:
+                       if handled.has_key(sn):
+                               continue
+
+                       success = True
+                       for dep in graph.get(sn, []):
+                               if not handled.has_key(dep):
+                                       success = False
+                       if success:
+                               snippets.insert(idx_deps, sn)
+                               idx_deps += 1
+                               snippets.insert(idx_deps, Snippet([ '' ]))
+                               idx_deps += 1
+                               handled[sn] = True
+                               keepgoing = True
+                               break
+
+       # XXX: detect and handle loops cleanly
+       for sn in snlist:
+               if handled.has_key(sn):
+                       continue
+               print('UNHANDLED KEY')
+               print('PROVIDES: %r' % sn.provides)
+               print('REQUIRES: %r' % sn.requires)
+               print('\n'.join(sn.lines))
+
+#      print(repr(graph))
+#      print(repr(snlist))
+#      print('Resolved helper defines: %r' % resolved)
+       print('Resolved %d helper defines' % len(resolved))
+
+def serialize_snippet_list(snippets):
+       ret = []
+
+       emitted_provides = {}
+       for k in assumed_provides.keys():
+               emitted_provides[k] = True
+
+       for sn in snippets:
+               ret += sn.lines
+               for k in sn.provides.keys():
+                       emitted_provides[k] = True
+               for k in sn.requires.keys():
+                       if not emitted_provides.has_key(k):
+                               # XXX: conditional warning, happens in some 
normal cases
+                               #print('WARNING: define %r required, not 
provided so far' % k)
+                               pass
+
+       return '\n'.join(ret)
+
+def remove_duplicate_newlines(x):
+       ret = []
+       empty = False
+       for line in x.split('\n'):
+               if line == '':
+                       if empty:
+                               pass
+                       else:
+                               ret.append(line)
+                       empty = True
+               else:
+                       empty = False
+                       ret.append(line)
+       return '\n'.join(ret)
+
+def scan_use_defs(dirname):
+       global use_defs, use_defs_list
+       use_defs = {}
+       use_defs_list = []
+
+       for fn in os.listdir(dirname):
+               root, ext = os.path.splitext(fn)
+               if not root.startswith('DUK_USE_') or ext != '.yaml':
+                       continue
+               with open(os.path.join(dirname, fn), 'rb') as f:
+                       doc = yaml.load(f)
+                       if doc.get('example', False):
+                               continue
+                       if doc.get('unimplemented', False):
+                               print('WARNING: unimplemented: %s' % fn)
+                               continue
+                       dockeys = doc.keys()
+                       for k in dockeys:
+                               if not k in allowed_use_meta_keys:
+                                       print('WARNING: unknown key %s in 
metadata file %s' % (k, fn))
+                       for k in required_use_meta_keys:
+                               if not k in dockeys:
+                                       print('WARNING: missing key %s in 
metadata file %s' % (k, fn))
+
+                       use_defs[doc['define']] = doc
+
+       keys = use_defs.keys()
+       keys.sort()
+       for k in keys:
+               use_defs_list.append(use_defs[k])
+
+def scan_opt_defs(dirname):
+       global opt_defs, opt_defs_list
+       opt_defs = {}
+       opt_defs_list = []
+
+       for fn in os.listdir(dirname):
+               root, ext = os.path.splitext(fn)
+               if not root.startswith('DUK_OPT_') or ext != '.yaml':
+                       continue
+               with open(os.path.join(dirname, fn), 'rb') as f:
+                       doc = yaml.load(f)
+                       if doc.get('example', False):
+                               continue
+                       if doc.get('unimplemented', False):
+                               print('WARNING: unimplemented: %s' % fn)
+                               continue
+                       dockeys = doc.keys()
+                       for k in dockeys:
+                               if not k in allowed_opt_meta_keys:
+                                       print('WARNING: unknown key %s in 
metadata file %s' % (k, fn))
+                       for k in required_opt_meta_keys:
+                               if not k in dockeys:
+                                       print('WARNING: missing key %s in 
metadata file %s' % (k, fn))
+
+                       opt_defs[doc['define']] = doc
+
+       keys = opt_defs.keys()
+       keys.sort()
+       for k in keys:
+               opt_defs_list.append(opt_defs[k])
+
+def scan_use_tags():
+       global use_tags, use_tags_list
+       use_tags = {}
+
+       for doc in use_defs_list:
+               for tag in doc.get('tags', []):
+                       use_tags[tag] = True
+
+       use_tags_list = use_tags.keys()
+       use_tags_list.sort()
+
+def scan_tags_meta(filename):
+       global tags_meta
+
+       with open(filename, 'rb') as f:
+               tags_meta = yaml.load(f)
+
+def scan_helper_snippets(dirname):  # DUK_F_xxx snippets
+       global helper_snippets
+       helper_snippets = []
+
+       for fn in os.listdir(dirname):
+               if (fn[0:6] != 'DUK_F_'):
+                       continue
+               #print('Autoscanning snippet: %s' % fn)
+               helper_snippets.append(Snippet.fromFile(os.path.join(dirname, 
fn)))
+
+def get_opt_defs(removed=True, deprecated=True, unused=True):
+       ret = []
+       for doc in opt_defs_list:
+               # XXX: aware of target version
+               if removed == False and doc.get('removed', None) is not None:
+                       continue
+               if deprecated == False and doc.get('deprecated', None) is not 
None:
+                       continue
+               if unused == False and doc.get('unused', False) == True:
+                       continue
+               ret.append(doc)
+       return ret
+
+def get_use_defs(removed=True, deprecated=True, unused=True):
+       ret = []
+       for doc in use_defs_list:
+               # XXX: aware of target version
+               if removed == False and doc.get('removed', None) is not None:
+                       continue
+               if deprecated == False and doc.get('deprecated', None) is not 
None:
+                       continue
+               if unused == False and doc.get('unused', False) == True:
+                       continue
+               ret.append(doc)
+       return ret
+
+def validate_platform_file(filename):
+       sn = Snippet.fromFile(filename)
+
+       for req in platform_required_provides:
+               if req not in sn.provides:
+                       raise Exception('Platform %s is missing %s' % 
(filename, req))
+
+       # DUK_SETJMP, DUK_LONGJMP, DUK_JMPBUF_TYPE are optional, fill-in
+       # provides if none defined.
+
+def validate_architecture_file(filename):
+       sn = Snippet.fromFile(filename)
+
+       for req in architecture_required_provides:
+               if req not in sn.provides:
+                       raise Exception('Architecture %s is missing %s' % 
(filename, req))
+
+       # Byte order and alignment defines are allowed to be missing,
+       # a fill-in will handle them.  This is necessary because for
+       # some architecture byte order and/or alignment may vary between
+       # targets and may be software configurable.
+
+       # XXX: require automatic detection to be signaled?
+       # e.g. define DUK_USE_ALIGN_BY -1
+       #      define DUK_USE_BYTE_ORDER -1
+
+def validate_compiler_file(filename):
+       sn = Snippet.fromFile(filename)
+
+       for req in compiler_required_provides:
+               if req not in sn.provides:
+                       raise Exception('Compiler %s is missing %s' % 
(filename, req))
+
+def get_tag_title(tag):
+       meta = tags_meta.get(tag, None)
+       if meta is None:
+               return tag
+       else:
+               return meta.get('title', tag)
+
+def get_tag_description(tag):
+       meta = tags_meta.get(tag, None)
+       if meta is None:
+               return None
+       else:
+               return meta.get('description', None)
+
+def get_tag_list_with_preferred_order(preferred):
+       tags = []
+
+       # Preferred tags first
+       for tag in preferred:
+               if tag not in tags:
+                       tags.append(tag)
+
+       # Remaining tags in alphabetic order
+       for tag in use_tags_list:
+               if tag not in tags:
+                       tags.append(tag)
+
+       #print('Effective tag order: %r' % tags)
+       return tags
+
+def rst_format(text):
+       # XXX: placeholder, need to decide on markup conventions for YAML files
+       ret = []
+       for para in text.split('\n'):
+               if para == '':
+                       continue
+               ret.append(para)
+       return '\n\n'.join(ret)
+
+def cint_encode(x):
+       if not isinstance(x, (int, long)):
+               raise Exception('invalid input: %r' % x)
+
+       # XXX: unsigned constants?
+       if x > 0x7fffffff or x < -0x80000000:
+               return '%dLL' % x
+       elif x > 0x7fff or x < -0x8000:
+               return '%dL' % x
+       else:
+               return '%d' % x
+
+def cstr_encode(x):
+       if isinstance(x, unicode):
+               x = x.encode('utf-8')
+       if not isinstance(x, str):
+               raise Exception('invalid input: %r' % x)
+
+       res = '"'
+       term = False
+       has_terms = False
+       for c in x:
+               if term:
+                       # Avoid ambiguous hex escapes
+                       res += '" "'
+                       term = False
+                       has_terms = True
+               o = ord(c)
+               if o < 0x20 or o > 0x7e or c in '"\\':
+                       res += '\\x%02x' % o
+                       term = True
+               else:
+                       res += c
+       res += '"'
+
+       if has_terms:
+               res = '(' + res + ')'
+
+       return res
+
+#
+#  Autogeneration of option documentation
+#
+
+# Shared helper to generate DUK_OPT_xxx and DUK_USE_xxx documentation.
+# XXX: unfinished placeholder
+def generate_option_documentation(opts, opt_list=None, rst_title=None, 
include_default=False):
+       ret = FileBuilder(use_cpp_warning=opts.use_cpp_warning)
+
+       tags = get_tag_list_with_preferred_order(doc_tag_order)
+
+       title = rst_title
+       ret.rst_heading(title, '=', doubled=True)
+
+       handled = {}
+
+       for tag in tags:
+               first = True
+
+               for doc in opt_list:
+                       if tag != doc['tags'][0]:  # sort under primary tag
+                               continue
+                       dname = doc['define']
+                       desc = doc.get('description', None)
+
+                       if handled.has_key(dname):
+                               raise Exception('define handled twice, should 
not happen: %r' % dname)
+                       handled[dname] = True
+
+                       if first:  # emit tag heading only if there are 
subsections
+                               ret.empty()
+                               ret.rst_heading(get_tag_title(tag), '=')
+
+                               tag_desc = get_tag_description(tag)
+                               if tag_desc is not None:
+                                       ret.empty()
+                                       ret.line(rst_format(tag_desc))
+                               first = False
+
+                       ret.empty()
+                       ret.rst_heading(dname, '-')
+
+                       if desc is not None:
+                               ret.empty()
+                               ret.line(rst_format(desc))
+
+                       if include_default:
+                               ret.empty()
+                               ret.line('Default: ``' + str(doc['default']) + 
'``')  # XXX: rst or other format
+
+       for doc in opt_list:
+               dname = doc['define']
+               if not handled.has_key(dname):
+                       raise Exception('unhandled define (maybe missing from 
tags list?): %r' % dname)
+
+       ret.empty()
+       return ret.join()
+
+def generate_feature_option_documentation(opts):
+       defs = get_opt_defs()
+       return generate_option_documentation(opts, opt_list=defs, 
rst_title='Duktape feature options', include_default=False)
+
+def generate_config_option_documentation(opts):
+       defs = get_use_defs()
+       return generate_option_documentation(opts, opt_list=defs, 
rst_title='Duktape config options', include_default=True)
+
+#
+#  Helpers for duk_config.h generation
+#
+
+def get_forced_options(opts):
+       # Forced options, last occurrence wins (allows a base config file to be
+       # overridden by a more specific one).
+       forced_opts = {}
+       for val in opts.force_options_yaml:
+               doc = yaml.load(StringIO(val))
+               for k in doc.keys():
+                       if use_defs.has_key(k):
+                               pass  # key is known
+                       else:
+                               print('WARNING: option override key %s not 
defined in metadata, ignoring' % k)
+                       forced_opts[k] = doc[k]  # shallow copy
+
+       if len(forced_opts.keys()) > 0:
+               print('Overrides: %s' % json.dumps(forced_opts))
+
+       return forced_opts
+
+# Emit a default #define / #undef for an option based on
+# a config option metadata node (parsed YAML doc).
+def emit_default_from_config_meta(ret, doc, forced_opts, undef_done):
+       defname = doc['define']
+       defval = forced_opts.get(defname, doc['default'])
+
+       # NOTE: careful with Python equality, e.g. "0 == False" is true.
+       if isinstance(defval, bool) and defval == True:
+               ret.line('#define ' + defname)
+       elif isinstance(defval, bool) and defval == False:
+               if not undef_done:
+                       ret.line('#undef ' + defname)
+               else:
+                       # Default value is false, and caller has emitted
+                       # an unconditional #undef, so don't emit a duplicate
+                       pass
+       elif isinstance(defval, (int, long)):
+               # integer value
+               ret.line('#define ' + defname + ' ' + cint_encode(defval))
+       elif isinstance(defval, (str, unicode)):
+               # verbatim value
+               ret.line('#define ' + defname + ' ' + defval)
+       elif isinstance(defval, dict):
+               if defval.has_key('verbatim'):
+                       # verbatim text for the entire line
+                       ret.line(defval['verbatim'])
+               elif defval.has_key('string'):
+                       # C string value
+                       ret.line('#define ' + defname + ' ' + 
cstr_encode(defval['string']))
+               else:
+                       raise Exception('unsupported value for option %s: %r' % 
(defname, defval))
+       else:
+               raise Exception('unsupported value for option %s: %r' % 
(defname, defval))
+
+# Add a header snippet for detecting presence of DUK_OPT_xxx feature
+# options which will be removed in Duktape 2.x.
+def add_legacy_feature_option_checks(opts, ret):
+       ret.chdr_block_heading('Checks for legacy feature options 
(DUK_OPT_xxx)')
+       ret.empty()
+
+       defs = []
+       for doc in get_opt_defs():
+               if doc['define'] not in defs:
+                       defs.append(doc['define'])
+       for doc in get_opt_defs():
+               for dname in doc.get('related_feature_defines', []):
+                       if dname not in defs:
+                               defs.append(dname)
+       defs.sort()
+
+       for optname in defs:
+               suggested = []
+               for doc in get_use_defs():
+                       if optname in doc.get('related_feature_defines', []):
+                               suggested.append(doc['define'])
+               ret.line('#if defined(%s)' % optname)
+               if len(suggested) > 0:
+                       ret.cpp_warning_or_error('unsupported legacy feature 
option %s used, consider options: %s' % (optname, ', '.join(suggested)), 
opts.sanity_strict)
+               else:
+                       ret.cpp_warning_or_error('unsupported legacy feature 
option %s used' % optname, opts.sanity_strict)
+               ret.line('#endif')
+
+       ret.empty()
+
+# Add a header snippet for checking consistency of DUK_USE_xxx config
+# options, e.g. inconsistent options, invalid option values.
+def add_config_option_checks(opts, ret):
+       ret.chdr_block_heading('Checks for config option consistency 
(DUK_USE_xxx)')
+       ret.empty()
+
+       defs = []
+       for doc in get_use_defs():
+               if doc['define'] not in defs:
+                       defs.append(doc['define'])
+       defs.sort()
+
+       for optname in defs:
+               doc = use_defs[optname]
+               dname = doc['define']
+
+               # XXX: more checks
+
+               if doc.get('removed', None) is not None:
+                       ret.line('#if defined(%s)' % dname)
+                       ret.cpp_warning_or_error('unsupported config option 
used (option has been removed): %s' % dname, opts.sanity_strict)
+                       ret.line('#endif')
+               elif doc.get('deprecated', None) is not None:
+                       ret.line('#if defined(%s)' % dname)
+                       ret.cpp_warning_or_error('unsupported config option 
used (option has been deprecated): %s' % dname, opts.sanity_strict)
+                       ret.line('#endif')
+
+               for req in doc.get('requires', []):
+                       ret.line('#if defined(%s) && !defined(%s)' % (dname, 
req))
+                       ret.cpp_warning_or_error('config option %s requires 
option %s (which is missing)' % (dname, req), opts.sanity_strict)
+                       ret.line('#endif')
+
+               for req in doc.get('conflicts', []):
+                       ret.line('#if defined(%s) && defined(%s)' % (dname, 
req))
+                       ret.cpp_warning_or_error('config option %s conflicts 
with option %s (which is also defined)' % (dname, req), opts.sanity_strict)
+                       ret.line('#endif')
+
+       ret.empty()
+       ret.snippet_relative('cpp_exception_sanity.h.in')
+       ret.empty()
+
+# Add a header snippet for providing a __OVERRIDE_DEFINES__ section.
+def add_override_defines_section(opts, ret):
+       ret.empty()
+       ret.line('/*')
+       ret.line(' *  You may add overriding #define/#undef directives below 
for')
+       ret.line(' *  customization.  You of course cannot un-#include or 
un-typedef')
+       ret.line(' *  anything; these require direct changes above.')
+       ret.line(' */')
+       ret.empty()
+       ret.line('/* __OVERRIDE_DEFINES__ */')
+       ret.empty()
+
+# Add automatic DUK_OPT_XXX and DUK_OPT_NO_XXX handling for backwards
+# compatibility with Duktape 1.2 and before.
+def add_feature_option_handling(opts, ret, forced_opts, already_provided_keys):
+       ret.chdr_block_heading('Feature option handling')
+
+       for doc in get_use_defs(removed=False, deprecated=False, unused=False):
+               # If a related feature option exists, it can be used to force
+               # enable/disable the target feature.  If neither feature option
+               # (DUK_OPT_xxx or DUK_OPT_NO_xxx) is given, revert to default.
+
+               config_define = doc['define']
+
+               feature_define = None
+               feature_no_define = None
+               inverted = False
+               if doc.has_key('feature_enables'):
+                       feature_define = doc['feature_enables']
+               elif doc.has_key('feature_disables'):
+                       feature_define = doc['feature_disables']
+                       inverted = True
+               else:
+                       pass
+
+               if feature_define is not None:
+                       feature_no_define = 'DUK_OPT_NO_' + feature_define[8:]
+                       ret.line('#if defined(%s)' % feature_define)
+                       if inverted:
+                               ret.line('#undef %s' % config_define)
+                       else:
+                               ret.line('#define %s' % config_define)
+                       ret.line('#elif defined(%s)' % feature_no_define)
+                       if inverted:
+                               ret.line('#define %s' % config_define)
+                       else:
+                               ret.line('#undef %s' % config_define)
+                       ret.line('#else')
+                       undef_done = False
+
+                       # For some options like DUK_OPT_PACKED_TVAL the default 
comes
+                       # from platform definition.
+                       if doc.get('feature_no_default', False):
+                               print('Skip default for option %s' % 
config_define)
+                               ret.line('/* Already provided above */')
+                       elif already_provided_keys.has_key(config_define):
+                               # This is a fallback in case config option 
metadata is wrong.
+                               print('Skip default for option %s (already 
provided but not flagged in metadata!)' % config_define)
+                               ret.line('/* Already provided above */')
+                       else:
+                               emit_default_from_config_meta(ret, doc, 
forced_opts, undef_done)
+                       ret.line('#endif')
+               elif doc.has_key('feature_snippet'):
+                       ret.lines(doc['feature_snippet'])
+               else:
+                       pass
+
+               ret.empty()
+
+       ret.empty()
+
+# Development time helper: add DUK_ACTIVE which provides a runtime C string
+# indicating what DUK_USE_xxx config options are active at run time.  This
+# is useful in genconfig development so that one can e.g. diff the active
+# run time options of two headers.  This is intended just for genconfig
+# development and is not available in normal headers.
+def add_duk_active_defines_macro(ret):
+       ret.chdr_block_heading('DUK_ACTIVE_DEFINES macro (development only)')
+
+       idx = 0
+       for doc in get_use_defs():
+               defname = doc['define']
+
+               ret.line('#if defined(%s)' % defname)
+               ret.line('#define DUK_ACTIVE_DEF%d " %s"' % (idx, defname))
+               ret.line('#else')
+               ret.line('#define DUK_ACTIVE_DEF%d ""' % idx)
+               ret.line('#endif')
+
+               idx += 1
+
+       tmp = []
+       for i in xrange(idx):
+               tmp.append('DUK_ACTIVE_DEF%d' % i)
+
+       ret.line('#define DUK_ACTIVE_DEFINES ("Active: ["' + ' '.join(tmp) + ' 
" ]")')
+
+#
+#  duk_config.h generation
+#
+
+# Generate a duk_config.h where platform, architecture, and compiler are
+# all either autodetected or specified by user.
+#
+# Autodetection is based on a configured list of supported platforms,
+# architectures, and compilers.  For example, platforms.yaml defines the
+# supported platforms and provides a helper define (DUK_F_xxx) to use for
+# detecting that platform, and names the header snippet to provide the
+# platform-specific definitions.  Necessary dependencies (DUK_F_xxx) are
+# automatically pulled in.
+#
+# Automatic "fill ins" are used for mandatory platform, architecture, and
+# compiler defines which have a reasonable portable default.  This reduces
+# e.g. compiler-specific define count because there are a lot compiler
+# macros which have a good default.
+def generate_duk_config_header(opts, meta_dir):
+       ret = FileBuilder(base_dir=os.path.join(meta_dir, 'header-snippets'), \
+                         use_cpp_warning=opts.use_cpp_warning)
+
+       forced_opts = get_forced_options(opts)
+
+       platforms = None
+       with open(os.path.join(meta_dir, 'platforms.yaml'), 'rb') as f:
+               platforms = yaml.load(f)
+       architectures = None
+       with open(os.path.join(meta_dir, 'architectures.yaml'), 'rb') as f:
+               architectures = yaml.load(f)
+       compilers = None
+       with open(os.path.join(meta_dir, 'compilers.yaml'), 'rb') as f:
+               compilers = yaml.load(f)
+
+       # XXX: indicate feature option support, sanity checks enabled, etc
+       # in general summary of options, perhaps genconfig command line?
+
+       ret.line('/*')
+       ret.line(' *  duk_config.h configuration header generated by 
genconfig.py.')
+       ret.line(' *')
+       ret.line(' *  Git commit: %s' % opts.git_commit or 'n/a')
+       ret.line(' *  Git describe: %s' % opts.git_describe or 'n/a')
+       ret.line(' *  Git branch: %s' % opts.git_branch or 'n/a')
+       ret.line(' *')
+       if opts.platform is not None:
+               ret.line(' *  Platform: ' + opts.platform)
+       else:
+               ret.line(' *  Supported platforms:')
+               for platf in platforms['autodetect']:
+                       ret.line(' *      - %s' % platf.get('name', 
platf.get('check')))
+       ret.line(' *')
+       if opts.architecture is not None:
+               ret.line(' *  Architecture: ' + opts.architecture)
+       else:
+               ret.line(' *  Supported architectures:')
+               for arch in architectures['autodetect']:
+                       ret.line(' *      - %s' % arch.get('name', 
arch.get('check')))
+       ret.line(' *')
+       if opts.compiler is not None:
+               ret.line(' *  Compiler: ' + opts.compiler)
+       else:
+               ret.line(' *  Supported compilers:')
+               for comp in compilers['autodetect']:
+                       ret.line(' *      - %s' % comp.get('name', 
comp.get('check')))
+       ret.line(' *')
+       ret.line(' */')
+       ret.empty()
+       ret.line('#if !defined(DUK_CONFIG_H_INCLUDED)')
+       ret.line('#define DUK_CONFIG_H_INCLUDED')
+       ret.empty()
+
+       ret.chdr_block_heading('Intermediate helper defines')
+
+       # DLL build affects visibility attributes on Windows but unfortunately
+       # cannot be detected automatically from preprocessor defines or such.
+       # DLL build status is hidden behind DUK_F_DLL_BUILD and there are two
+       # ways for that to be set:
+       #
+       #   - Duktape 1.3 backwards compatible DUK_OPT_DLL_BUILD
+       #   - Genconfig --dll option
+       ret.chdr_comment_line('DLL build detection')
+       ret.line('#if defined(DUK_OPT_DLL_BUILD)')
+       ret.line('#define DUK_F_DLL_BUILD')
+       ret.line('#elif defined(DUK_OPT_NO_DLL_BUILD)')
+       ret.line('#undef DUK_F_DLL_BUILD')
+       ret.line('#else')
+       if opts.dll:
+               ret.line('/* configured for DLL build */')
+               ret.line('#define DUK_F_DLL_BUILD')
+       else:
+               ret.line('/* not configured for DLL build */')
+               ret.line('#undef DUK_F_DLL_BUILD')
+       ret.line('#endif')
+       ret.empty()
+
+       idx_deps = len(ret.vals)  # position where to emit DUK_F_xxx 
dependencies
+
+       # Feature selection, system include, Date provider
+       # Most #include statements are here
+
+       if opts.platform is not None:
+               ret.chdr_block_heading('Platform: ' + opts.platform)
+
+               ret.snippet_relative('platform_cppextras.h.in')
+               ret.empty()
+
+               # XXX: better to lookup platforms metadata
+               include = 'platform_%s.h.in' % opts.platform
+               abs_fn = os.path.join(meta_dir, 'platforms', include)
+               validate_platform_file(abs_fn)
+               ret.snippet_absolute(abs_fn)
+       else:
+               ret.chdr_block_heading('Platform autodetection')
+
+               ret.snippet_relative('platform_cppextras.h.in')
+               ret.empty()
+
+               for idx, platf in enumerate(platforms['autodetect']):
+                       check = platf.get('check', None)
+                       include = platf['include']
+                       abs_fn = os.path.join(meta_dir, 'platforms', include)
+
+                       validate_platform_file(abs_fn)
+
+                       if idx == 0:
+                               ret.line('#if defined(%s)' % check)
+                       else:
+                               if check is None:
+                                       ret.line('#else')
+                               else:
+                                       ret.line('#elif defined(%s)' % check)
+                       ret.line('/* --- %s --- */' % platf.get('name', '???'))
+                       ret.snippet_absolute(abs_fn)
+               ret.line('#endif  /* autodetect platform */')
+
+       ret.empty()
+       ret.snippet_relative('platform_sharedincludes.h.in')
+       ret.empty()
+
+       byteorder_provided_by_all = True  # byteorder provided by all 
architecture files
+       alignment_provided_by_all = True  # alignment provided by all 
architecture files
+       packedtval_provided_by_all = True # packed tval provided by all 
architecture files
+
+       if opts.architecture is not None:
+               ret.chdr_block_heading('Architecture: ' + opts.architecture)
+
+               # XXX: better to lookup architectures metadata
+               include = 'architecture_%s.h.in' % opts.architecture
+               abs_fn = os.path.join(meta_dir, 'architectures', include)
+               validate_architecture_file(abs_fn)
+               sn = ret.snippet_absolute(abs_fn)
+               if not sn.provides.get('DUK_USE_BYTEORDER', False):
+                       byteorder_provided_by_all = False
+               if not sn.provides.get('DUK_USE_ALIGN_BY', False):
+                       alignment_provided_by_all = False
+               if sn.provides.get('DUK_USE_PACKED_TVAL', False):
+                       ret.line('#define DUK_F_PACKED_TVAL_PROVIDED')  # 
signal to fillin
+               else:
+                       packedtval_provided_by_all = False
+       else:
+               ret.chdr_block_heading('Architecture autodetection')
+
+               for idx, arch in enumerate(architectures['autodetect']):
+                       check = arch.get('check', None)
+                       include = arch['include']
+                       abs_fn = os.path.join(meta_dir, 'architectures', 
include)
+
+                       validate_architecture_file(abs_fn)
+
+                       if idx == 0:
+                               ret.line('#if defined(%s)' % check)
+                       else:
+                               if check is None:
+                                       ret.line('#else')
+                               else:
+                                       ret.line('#elif defined(%s)' % check)
+                       ret.line('/* --- %s --- */' % arch.get('name', '???'))
+                       sn = ret.snippet_absolute(abs_fn)
+                       if not sn.provides.get('DUK_USE_BYTEORDER', False):
+                               byteorder_provided_by_all = False
+                       if not sn.provides.get('DUK_USE_ALIGN_BY', False):
+                               alignment_provided_by_all = False
+                       if sn.provides.get('DUK_USE_PACKED_TVAL', False):
+                               ret.line('#define DUK_F_PACKED_TVAL_PROVIDED')  
# signal to fillin
+                       else:
+                               packedtval_provided_by_all = False
+               ret.line('#endif  /* autodetect architecture */')
+
+       ret.empty()
+
+       if opts.compiler is not None:
+               ret.chdr_block_heading('Compiler: ' + opts.compiler)
+
+               # XXX: better to lookup compilers metadata
+               include = 'compiler_%s.h.in' % opts.compiler
+               abs_fn = os.path.join(meta_dir, 'compilers', include)
+               validate_compiler_file(abs_fn)
+               sn = ret.snippet_absolute(abs_fn)
+       else:
+               ret.chdr_block_heading('Compiler autodetection')
+
+               for idx, comp in enumerate(compilers['autodetect']):
+                       check = comp.get('check', None)
+                       include = comp['include']
+                       abs_fn = os.path.join(meta_dir, 'compilers', include)
+
+                       validate_compiler_file(abs_fn)
+
+                       if idx == 0:
+                               ret.line('#if defined(%s)' % check)
+                       else:
+                               if check is None:
+                                       ret.line('#else')
+                               else:
+                                       ret.line('#elif defined(%s)' % check)
+                       ret.line('/* --- %s --- */' % comp.get('name', '???'))
+                       sn = ret.snippet_absolute(abs_fn)
+               ret.line('#endif  /* autodetect compiler */')
+
+       ret.empty()
+
+       # DUK_F_UCLIBC is special because __UCLIBC__ is provided by an #include
+       # file, so the check must happen after platform includes.  It'd be nice
+       # for this to be automatic (e.g. DUK_F_UCLIBC.h.in could indicate the
+       # dependency somehow).
+
+       ret.snippet_absolute(os.path.join(meta_dir, 'helper-snippets', 
'DUK_F_UCLIBC.h.in'))
+       ret.empty()
+
+       # XXX: platform/compiler could provide types; if so, need some signaling
+       # defines like DUK_F_TYPEDEFS_DEFINED
+
+       # Number types
+       if opts.c99_types_only:
+               ret.snippet_relative('types1.h.in')
+               ret.line('/* C99 types assumed */')
+               ret.snippet_relative('types_c99.h.in')
+               ret.empty()
+       else:
+               ret.snippet_relative('types1.h.in')
+               ret.line('#if defined(DUK_F_HAVE_INTTYPES)')
+               ret.line('/* C99 or compatible */')
+               ret.empty()
+               ret.snippet_relative('types_c99.h.in')
+               ret.empty()
+               ret.line('#else  /* C99 types */')
+               ret.empty()
+               ret.snippet_relative('types_legacy.h.in')
+               ret.empty()
+               ret.line('#endif  /* C99 types */')
+               ret.empty()
+       ret.snippet_relative('types2.h.in')
+       ret.empty()
+       ret.snippet_relative('64bitops.h.in')
+       ret.empty()
+
+       # Platform, architecture, compiler fillins.  These are after all
+       # detection so that e.g. DUK_SPRINTF() can be provided by platform
+       # or compiler before trying a fill-in.
+
+       ret.chdr_block_heading('Fill-ins for platform, architecture, and 
compiler')
+
+       ret.snippet_relative('platform_fillins.h.in')
+       ret.empty()
+       ret.snippet_relative('architecture_fillins.h.in')
+       if not byteorder_provided_by_all:
+               ret.empty()
+               ret.snippet_relative('byteorder_fillin.h.in')
+       if not alignment_provided_by_all:
+               ret.empty()
+               ret.snippet_relative('alignment_fillin.h.in')
+       ret.empty()
+       ret.snippet_relative('compiler_fillins.h.in')
+       ret.empty()
+       ret.snippet_relative('inline_workaround.h.in')
+       ret.empty()
+       if not packedtval_provided_by_all:
+               ret.empty()
+               ret.snippet_relative('packed_tval_fillin.h.in')
+
+       # Object layout
+       ret.snippet_relative('object_layout.h.in')
+       ret.empty()
+
+       # Detect and reject 'fast math'
+       ret.snippet_relative('reject_fast_math.h.in')
+       ret.empty()
+
+       # Automatic DUK_OPT_xxx feature option handling
+       if opts.support_feature_options:
+               print('Autogenerating feature option (DUK_OPT_xxx) support')
+               tmp = Snippet(ret.join().split('\n'))
+               add_feature_option_handling(opts, ret, forced_opts, 
tmp.provides)
+
+       # Emit forced options.  If a corresponding option is already defined
+       # by a snippet above, #undef it first.
+
+       tmp = Snippet(ret.join().split('\n'))
+       first_forced = True
+       for doc in get_use_defs(removed=not opts.omit_removed_config_options,
+                               deprecated=not 
opts.omit_deprecated_config_options,
+                               unused=not opts.omit_unused_config_options):
+               defname = doc['define']
+
+               if not forced_opts.has_key(defname):
+                       continue
+
+               if not doc.has_key('default'):
+                       raise Exception('config option %s is missing default 
value' % defname)
+
+               if first_forced:
+                       ret.chdr_block_heading('Forced options')
+                       first_forced = False
+
+               undef_done = False
+               if tmp.provides.has_key(defname):
+                       ret.line('#undef ' + defname)
+                       undef_done = True
+
+               emit_default_from_config_meta(ret, doc, forced_opts, undef_done)
+
+       ret.empty()
+
+       # If manually-edited snippets don't #define or #undef a certain
+       # config option, emit a default value here.  This is useful to
+       # fill-in for new config options not covered by manual snippets
+       # (which is intentional).
+
+       tmp = Snippet(ret.join().split('\n'))
+       need = {}
+       for doc in get_use_defs(removed=False):
+               need[doc['define']] = True
+       for k in tmp.provides.keys():
+               if need.has_key(k):
+                       del need[k]
+       need_keys = sorted(need.keys())
+
+       if len(need_keys) > 0:
+               ret.chdr_block_heading('Autogenerated defaults')
+
+               for k in need_keys:
+                       #print('config option %s not covered by manual 
snippets, emitting default automatically' % k)
+                       emit_default_from_config_meta(ret, use_defs[k], {}, 
False)
+
+               ret.empty()
+
+       ret.snippet_relative('custom_header.h.in')
+       ret.empty()
+
+       if len(opts.fixup_header_lines) > 0:
+               ret.chdr_block_heading('Fixups')
+               for line in opts.fixup_header_lines:
+                       ret.line(line)
+               ret.empty()
+
+       add_override_defines_section(opts, ret)
+
+       # Date provider snippet is after custom header and overrides, so that
+       # the user may define e.g. DUK_USE_DATE_NOW_GETTIMEOFDAY in their
+       # custom header.
+       ret.snippet_relative('date_provider.h.in')
+       ret.empty()
+
+       ret.fill_dependencies_for_snippets(idx_deps)
+
+       if opts.emit_legacy_feature_check:
+               add_legacy_feature_option_checks(opts, ret)
+       if opts.emit_config_sanity_check:
+               add_config_option_checks(opts, ret)
+       if opts.add_active_defines_macro:
+               add_duk_active_defines_macro(ret)
+
+       # Derived defines (DUK_USE_INTEGER_LE, etc) from DUK_USE_BYTEORDER.
+       # Duktape internals currently rely on the derived defines.  This is
+       # after sanity checks because the derived defines are marked removed.
+       ret.snippet_relative('byteorder_derived.h.in')
+       ret.empty()
+
+       ret.line('#endif  /* DUK_CONFIG_H_INCLUDED */')
+       ret.empty()  # for trailing newline
+       return remove_duplicate_newlines(ret.join())
+
+#
+#  Main
+#
+
+def main():
+       # Forced options from multiple sources are gathered into a shared list
+       # so that the override order remains the same as on the command line.
+       force_options_yaml = []
+       def add_force_option_yaml(option, opt, value, parser):
+               # XXX: check that YAML parses
+               force_options_yaml.append(value)
+       def add_force_option_file(option, opt, value, parser):
+               # XXX: check that YAML parses
+               with open(value, 'rb') as f:
+                       force_options_yaml.append(f.read())
+       def add_force_option_define(option, opt, value, parser):
+               tmp = value.split('=')
+               if len(tmp) == 1:
+                       doc = { tmp[0]: True }
+               elif len(tmp) == 2:
+                       doc = { tmp[0]: tmp[1] }
+               else:
+                       raise Exception('invalid option value: %r' % value)
+               force_options_yaml.append(yaml.safe_dump(doc))
+       def add_force_option_undefine(option, opt, value, parser):
+               tmp = value.split('=')
+               if len(tmp) == 1:
+                       doc = { tmp[0]: False }
+               else:
+                       raise Exception('invalid option value: %r' % value)
+               force_options_yaml.append(yaml.safe_dump(doc))
+
+       fixup_header_lines = []
+       def add_fixup_header_line(option, opt, value, parser):
+               fixup_header_lines.append(value)
+       def add_fixup_header_file(option, opt, value, parser):
+               with open(value, 'rb') as f:
+                       for line in f:
+                               if line[-1] == '\n':
+                                       line = line[:-1]
+                               fixup_header_lines.append(line)
+
+       commands = [
+               'duk-config-header',
+               'feature-documentation',
+               'config-documentation'
+       ]
+       parser = optparse.OptionParser(
+               usage='Usage: %prog [options] COMMAND',
+               description='Generate a duk_config.h or config option 
documentation based on config metadata.',
+               epilog='COMMAND can be one of: ' + ', '.join(commands) + '.'
+       )
+
+       parser.add_option('--metadata', dest='metadata', default=None, 
help='metadata directory or metadata tar.gz file')
+       parser.add_option('--output', dest='output', default=None, help='output 
filename for C header or RST documentation file')
+       parser.add_option('--platform', dest='platform', default=None, 
help='platform (for "barebones-header" command)')
+       parser.add_option('--compiler', dest='compiler', default=None, 
help='compiler (for "barebones-header" command)')
+       parser.add_option('--architecture', dest='architecture', default=None, 
help='architecture (for "barebones-header" command)')
+       parser.add_option('--c99-types-only', dest='c99_types_only', 
action='store_true', default=False, help='assume C99 types, no legacy type 
detection')
+       parser.add_option('--dll', dest='dll', action='store_true', 
default=False, help='dll build of Duktape, affects symbol visibility macros 
especially on Windows')
+       parser.add_option('--support-feature-options', 
dest='support_feature_options', action='store_true', default=False, 
help='support DUK_OPT_xxx feature options in duk_config.h')
+       parser.add_option('--emit-legacy-feature-check', 
dest='emit_legacy_feature_check', action='store_true', default=False, 
help='emit preprocessor checks to reject legacy feature options (DUK_OPT_xxx)')
+       parser.add_option('--emit-config-sanity-check', 
dest='emit_config_sanity_check', action='store_true', default=False, help='emit 
preprocessor checks for config option consistency (DUK_OPT_xxx)')
+       parser.add_option('--omit-removed-config-options', 
dest='omit_removed_config_options', action='store_true', default=False, 
help='omit removed config options from generated headers')
+       parser.add_option('--omit-deprecated-config-options', 
dest='omit_deprecated_config_options', action='store_true', default=False, 
help='omit deprecated config options from generated headers')
+       parser.add_option('--omit-unused-config-options', 
dest='omit_unused_config_options', action='store_true', default=False, 
help='omit unused config options from generated headers')
+       parser.add_option('--add-active-defines-macro', 
dest='add_active_defines_macro', action='store_true', default=False, help='add 
DUK_ACTIVE_DEFINES macro, for development only')
+       parser.add_option('--define', type='string', dest='force_options_yaml', 
action='callback', callback=add_force_option_define, 
default=force_options_yaml, help='force #define option using a C compiler like 
syntax, e.g. "--define DUK_USE_DEEP_C_STACK" or "--define 
DUK_USE_TRACEBACK_DEPTH=10"')
+       parser.add_option('-D', type='string', dest='force_options_yaml', 
action='callback', callback=add_force_option_define, 
default=force_options_yaml, help='synonym for --define, e.g. 
"-DDUK_USE_DEEP_C_STACK" or "-DDUK_USE_TRACEBACK_DEPTH=10"')
+       parser.add_option('--undefine', type='string', 
dest='force_options_yaml', action='callback', 
callback=add_force_option_undefine, default=force_options_yaml, help='force 
#undef option using a C compiler like syntax, e.g. "--undefine 
DUK_USE_DEEP_C_STACK"')
+       parser.add_option('-U', type='string', dest='force_options_yaml', 
action='callback', callback=add_force_option_undefine, 
default=force_options_yaml, help='synonym for --undefine, e.g. 
"-UDUK_USE_DEEP_C_STACK"')
+       parser.add_option('--option-yaml', type='string', 
dest='force_options_yaml', action='callback', callback=add_force_option_yaml, 
default=force_options_yaml, help='force option(s) using inline YAML (e.g. 
--option-yaml "DUK_USE_DEEP_C_STACK: true")')
+       parser.add_option('--option-file', type='string', 
dest='force_options_yaml', action='callback', callback=add_force_option_file, 
default=force_options_yaml, help='YAML file(s) providing config option 
overrides')
+       parser.add_option('--fixup-file', type='string', 
dest='fixup_header_lines', action='callback', callback=add_fixup_header_file, 
default=fixup_header_lines, help='C header snippet file(s) to be appended to 
generated header, useful for manual option fixups')
+       parser.add_option('--fixup-line', type='string', 
dest='fixup_header_lines', action='callback', callback=add_fixup_header_line, 
default=fixup_header_lines, help='C header fixup line to be appended to 
generated header (e.g. --fixup-line "#define DUK_USE_FASTINT")')
+       parser.add_option('--sanity-warning', dest='sanity_strict', 
action='store_false', default=True, help='emit a warning instead of #error for 
option sanity check issues')
+       parser.add_option('--use-cpp-warning', dest='use_cpp_warning', 
action='store_true', default=False, help='emit a (non-portable) #warning when 
appropriate')
+       parser.add_option('--git-commit', dest='git_commit', default=None, 
help='git commit hash to be included in header comments')
+       parser.add_option('--git-describe', dest='git_describe', default=None, 
help='git describe string to be included in header comments')
+       parser.add_option('--git-branch', dest='git_branch', default=None, 
help='git branch string to be included in header comments')
+       (opts, args) = parser.parse_args()
+
+       meta_dir = opts.metadata
+       if opts.metadata is None:
+               if os.path.isfile(os.path.join('.', 
'genconfig_metadata.tar.gz')):
+                       opts.metadata = 'genconfig_metadata.tar.gz'
+               elif os.path.isdir(os.path.join('.', 'config-options')):
+                       opts.metadata = '.'
+
+       if opts.metadata is not None and os.path.isdir(opts.metadata):
+               meta_dir = opts.metadata
+               metadata_src_text = 'Using metadata directory: %r' % meta_dir
+       elif opts.metadata is not None and os.path.isfile(opts.metadata) and 
tarfile.is_tarfile(opts.metadata):
+               meta_dir = get_auto_delete_tempdir()
+               tar = tarfile.open(name=opts.metadata, mode='r:*')
+               tar.extractall(path=meta_dir)
+               metadata_src_text = 'Using metadata tar file %r, unpacked to 
directory: %r' % (opts.metadata, meta_dir)
+       else:
+               raise Exception('metadata source must be a directory or a 
tar.gz file')
+
+       scan_helper_snippets(os.path.join(meta_dir, 'helper-snippets'))
+       scan_use_defs(os.path.join(meta_dir, 'config-options'))
+       scan_opt_defs(os.path.join(meta_dir, 'feature-options'))
+       scan_use_tags()
+       scan_tags_meta(os.path.join(meta_dir, 'tags.yaml'))
+       print('%s, scanned %d DUK_OPT_xxx, %d DUK_USE_XXX, %d helper snippets' 
% \
+               (metadata_src_text, len(opt_defs.keys()), len(use_defs.keys()), 
len(helper_snippets)))
+       #print('Tags: %r' % use_tags_list)
+
+       if len(args) == 0:
+               raise Exception('missing command')
+       cmd = args[0]
+
+       # Compatibility with Duktape 1.3
+       if cmd == 'autodetect-header':
+               cmd = 'duk-config-header'
+       if cmd == 'barebones-header':
+               cmd = 'duk-config-header'
+
+       if cmd == 'duk-config-header':
+               # Generate a duk_config.h header with platform, compiler, and
+               # architecture either autodetected (default) or specified by
+               # user.  Support for autogenerated DUK_OPT_xxx flags is also
+               # selected by user.
+               result = generate_duk_config_header(opts, meta_dir)
+               with open(opts.output, 'wb') as f:
+                       f.write(result)
+       elif cmd == 'feature-documentation':
+               result = generate_feature_option_documentation(opts)
+               with open(opts.output, 'wb') as f:
+                       f.write(result)
+       elif cmd == 'config-documentation':
+               result = generate_config_option_documentation(opts)
+               with open(opts.output, 'wb') as f:
+                       f.write(result)
+       else:
+               raise Exception('invalid command: %r' % cmd)
+
+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/config/genconfig_metadata.tar.gz
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/config/genconfig_metadata.tar.gz
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/config/genconfig_metadata.tar.gz
new file mode 100644
index 0000000..c34b2ef
Binary files /dev/null and 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/config/genconfig_metadata.tar.gz
 differ

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/debugger/README.rst
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/debugger/README.rst 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/debugger/README.rst
new file mode 100644
index 0000000..f60b350
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/debugger/README.rst
@@ -0,0 +1,384 @@
+=========================================
+Duktape debug client and JSON debug proxy
+=========================================
+
+Overview
+========
+
+Debugger web UI which connects to the Duktape command line tool or any other
+target supporting the example TCP transport (``examples/debug-trans-socket``)
+on Unix and Windows.
+
+Also provides a JSON debug proxy with a JSON mapping for the Duktape debug
+protocol.
+
+For detailed documentation of the debugger internals, see `debugger.rst`__.
+
+__ https://github.com/svaarala/duktape/blob/master/doc/debugger.rst
+
+Using the debugger web UI
+=========================
+
+Some prerequisites:
+
+* You'll need Node.js v0.10.x or newer.  Older Node.js versions don't support
+  the required packages.
+
+Compile Duktape command line tool with debugger support (for further options
+see http://wiki.duktape.org/FeatureOptions.html):
+
+* ``DUK_OPT_DEBUGGER_SUPPORT``
+
+* ``DUK_OPT_INTERRUPT_COUNTER``
+
+* ``DUK_CMDLINE_DEBUGGER_SUPPORT``
+
+The source distributable contains a Makefile to build a "duk" command with
+debugger support::
+
+    $ cd <duktape dist directory>
+    $ make -f Makefile.dukdebug
+
+The Duktape Git repo "duk" target has debugger support enabled by default::
+
+    $ make clean duk
+
+Start Duktape command line tool so that it waits for a debugger connection::
+
+    # For now we need to be in the directory containing the source files
+    # executed so that the 'fileName' properties of functions will match
+    # that on the debug client.
+
+    # Using source distributable
+    $ cd <duktape dist directory>
+    $ ./duk --debugger mandel.js
+
+    # Using Duktape Git repo
+    $ cd <duktape checkout>/tests/ecmascript/
+    $ ../../duk --debugger test-dev-mandel2-func.js
+
+Start the web UI::
+
+    # Must be in 'debugger' directory.
+
+    $ cd debugger/
+    $ make  # runs 'node duk_debug.js'
+
+Once the required packages are installed, the NodeJS debug client will be
+up and running.  Open the following in your browser and start debugging:
+
+* http://localhost:9092/
+
+The debug client automatically attaches to the debug target on startup.
+If you start the debug target later, you'll need to click "Attach" in the
+web UI.
+
+Using the JSON debug proxy
+==========================
+
+There are two JSON debug proxy implementations: one implemented in DukLuv
+and another in Node.js.
+
+DukLuv JSON proxy
+-----------------
+
+DukLuv (https://github.com/creationix/dukluv) is a small and portable event
+loop based on LibUV and Duktape with MIT license (like Duktape).  As such it's
+easy to embed in a custom debug client: you just include the DukLuv executable
+and the JSON proxy source file in your debug client.
+
+Install DukLuv:
+
+* Ensure ``cmake`` is installed
+
+* ``git clone https://github.com/creationix/dukluv.git``
+
+* ``git submodule init; git submodule update``
+
+* ``make``
+
+* Binary should appear in:
+
+  - ``./build/dukluv`` on Linux
+
+  - ``.\build\Debug\dukluv.exe`` on Windows
+
+Run the proxy::
+
+    # Using Makefile; autogenerates duk_debug_meta.json
+    # (You may need to edit DUKLUV in Makefile to point to your DukLuv)
+    $ make runproxydukluv
+
+    # Manually: see "dukluv duk_debug_proxy.js --help" for help
+    $ .../path/to/dukluv duk_debug_proxy.js
+
+Start Duktape command line (or whatever your target is)::
+
+    $ cd <duktape checkout>/tests/ecmascript/
+    $ ../../duk --debugger test-dev-mandel2-func.js
+
+Now connect to the proxy using e.g. telnet::
+
+    $ telnet localhost 9093
+
+The proxy will then connect to the target and you can start issuing commands::
+
+    $ telnet localhost 9093
+    Trying 127.0.0.1...
+    Connected to localhost.
+    Escape character is '^]'.
+    {"notify":"_TargetConnecting","args":["127.0.0.1",9091]}
+    {"notify":"_TargetConnected","args":["1 10499 v1.4.0-140-gc9a6c7c duk 
command built from Duktape repo"]}
+    
{"notify":"Status","command":1,"args":[1,"test-dev-mandel2-func.js","global",58,0]}
+    {"request":"BasicInfo"}
+    {"reply":true,"args":[10499,"v1.4.0-140-gc9a6c7c","duk command built from 
Duktape repo",1]}
+    {"request":"Eval","args":["print('Hello world!'); 123;"]}
+    {"notify":"Print","command":2,"args":["Hello world!\n"]}
+    {"reply":true,"args":[0,{"type":"number","data":"405ec00000000000"}]}
+    [...]
+
+The proxy log provides dumps both JSON and dvalue binary traffic which is
+quite useful in development::
+
+    $ make runproxydukluv
+    Running Dukluv based debug proxy
+    "dukluv" duk_debug_proxy.js --log-level 2 --metadata duk_debug_meta.json
+    2016-02-17T13:59:42.308Z INF Proxy: Read proxy metadata from 
duk_debug_meta.json
+    2016-02-17T13:59:42.325Z INF Proxy: Listening for incoming JSON debug 
connection on 0.0.0.0:9093, target is 127.0.0.1:9091
+    2016-02-17T13:59:47.994Z INF Proxy: JSON proxy client connected
+    2016-02-17T13:59:47.994Z INF Proxy: Connecting to debug target at 
127.0.0.1:9091
+    2016-02-17T13:59:47.994Z INF Proxy: PROXY --> CLIENT: 
{"notify":"_TargetConnecting","args":["127.0.0.1",9091]}
+    2016-02-17T13:59:47.994Z INF Proxy: Connected to debug target at 
127.0.0.1:9091
+    2016-02-17T13:59:48.003Z INF Proxy: PROXY --> CLIENT: 
{"notify":"_TargetConnected","args":["1 10499 v1.4.0-140-gc9a6c7c duk command 
built from Duktape repo"]}
+    2016-02-17T13:59:48.003Z INF Proxy: Target handshake: {"line":"1 10499 
v1.4.0-140-gc9a6c7c duk command built from Duktape 
repo","protocolVersion":1,"text":"10499 v1.4.0-140-gc9a6c7c duk command built 
from Duktape 
repo","dukVersion":"1","dukGitDescribe":"10499","targetString":"v1.4.0-140-gc9a6c7c"}
+    2016-02-17T13:59:48.151Z INF Proxy: PROXY <-- TARGET: |04|
+    2016-02-17T13:59:48.152Z INF Proxy: PROXY <-- TARGET: |81|
+    2016-02-17T13:59:48.152Z INF Proxy: PROXY <-- TARGET: |81|
+    2016-02-17T13:59:48.160Z INF Proxy: PROXY <-- TARGET: 
|78746573742d6465762d6d616e64656c322d66756e632e6a73|
+    2016-02-17T13:59:48.161Z INF Proxy: PROXY <-- TARGET: |66676c6f62616c|
+    2016-02-17T13:59:48.165Z INF Proxy: PROXY <-- TARGET: |ba|
+    2016-02-17T13:59:48.165Z INF Proxy: PROXY <-- TARGET: |80|
+    2016-02-17T13:59:48.165Z INF Proxy: PROXY <-- TARGET: |00|
+    2016-02-17T13:59:48.165Z INF Proxy: PROXY --> CLIENT: 
{"notify":"Status","command":1,"args":[1,"test-dev-mandel2-func.js","global",58,0]}
+    2016-02-17T13:59:51.289Z INF Proxy: PROXY <-- CLIENT: 
{"request":"BasicInfo"}
+    2016-02-17T13:59:51.289Z INF Proxy: PROXY --> TARGET: |01|
+    2016-02-17T13:59:51.289Z INF Proxy: PROXY --> TARGET: |90|
+    2016-02-17T13:59:51.289Z INF Proxy: PROXY --> TARGET: |00|
+    2016-02-17T13:59:51.291Z INF Proxy: PROXY <-- TARGET: |02|
+    2016-02-17T13:59:51.291Z INF Proxy: PROXY <-- TARGET: |e903|
+    2016-02-17T13:59:51.292Z INF Proxy: PROXY <-- TARGET: 
|7376312e342e302d3134302d6763396136633763|
+    2016-02-17T13:59:51.293Z INF Proxy: PROXY <-- TARGET: 
|12002364756b20636f6d6d616e64206275696c742066726f6d2044756b74617065207265706f|
+    2016-02-17T13:59:51.293Z INF Proxy: PROXY <-- TARGET: |81|
+    2016-02-17T13:59:51.293Z INF Proxy: PROXY <-- TARGET: |00|
+    2016-02-17T13:59:51.293Z INF Proxy: PROXY --> CLIENT: 
{"reply":true,"args":[10499,"v1.4.0-140-gc9a6c7c","duk command built from 
Duktape repo",1]}
+    2016-02-17T14:00:06.105Z INF Proxy: PROXY <-- CLIENT: 
{"request":"Eval","args":["print('Hello world!'); 123;"]}
+    2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |01|
+    2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |9e|
+    2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: 
|7b7072696e74282748656c6c6f20776f726c642127293b203132333b|
+    2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |00|
+    2016-02-17T14:00:06.167Z INF Proxy: PROXY <-- TARGET: |04|
+    2016-02-17T14:00:06.167Z INF Proxy: PROXY <-- TARGET: |82|
+    2016-02-17T14:00:06.167Z INF Proxy: PROXY <-- TARGET: 
|6d48656c6c6f20776f726c64210a|
+    2016-02-17T14:00:06.168Z INF Proxy: PROXY <-- TARGET: |00|
+    2016-02-17T14:00:06.168Z INF Proxy: PROXY --> CLIENT: 
{"notify":"Print","command":2,"args":["Hello world!\n"]}
+    2016-02-17T14:00:06.171Z INF Proxy: PROXY <-- TARGET: |02|
+    2016-02-17T14:00:06.171Z INF Proxy: PROXY <-- TARGET: |80|
+    2016-02-17T14:00:06.173Z INF Proxy: PROXY <-- TARGET: |1a405ec00000000000|
+    2016-02-17T14:00:06.173Z INF Proxy: PROXY <-- TARGET: |00|
+    2016-02-17T14:00:06.174Z INF Proxy: PROXY --> CLIENT: 
{"reply":true,"args":[0,{"type":"number","data":"405ec00000000000"}]}
+    [...]
+
+Node.js JSON proxy
+------------------
+
+A Node.js-based JSON debug proxy is also provided by ``duk_debug.js``::
+
+    # Same prerequisites as for running the debug client
+    $ make runproxynodejs
+
+Start Duktape command line (or whatever your target is)::
+
+    $ cd <duktape checkout>/tests/ecmascript/
+    $ ../../duk --debugger test-dev-mandel2-func.js
+
+You can then connect to localhost:9093 and interact with the proxy.
+Here's an example session using telnet and manually typed in commands
+The ``-->`` (send) and ``<--`` (receiver) markers have been added for
+readability and are not part of the stream::
+
+    $ telnet localhost 9093
+    Trying 127.0.0.1...
+    Connected to localhost.
+    Escape character is '^]'.
+    <-- {"notify":"_TargetConnected","args":["1 10199 
v1.1.0-275-gbd4d610-dirty duk command built from Duktape repo"]}
+    <-- 
{"notify":"Status","command":1,"args":[1,"test-dev-mandel2-func.js","global",58,0]}
+    --> {"request":"BasicInfo"}
+    <-- {"reply":true,"args":[10199,"v1.1.0-275-gbd4d610-dirty","duk command 
built from Duktape repo",1]}
+    --> {"request":"Eval", "args":[ "print(Math.PI)" ]}
+    <-- {"notify":"Print","command":2,"args":["3.141592653589793\n"]}
+    <-- {"reply":true,"args":[0,{"type":"undefined"}]}
+    --> {"request":"Resume"}
+    <-- {"reply":true,"args":[]}
+    <-- 
{"notify":"Status","command":1,"args":[0,"test-dev-mandel2-func.js","global",58,0]}
+    <-- 
{"notify":"Status","command":1,"args":[0,"test-dev-mandel2-func.js","global",58,0]}
+    <-- 
{"notify":"Print","command":2,"args":["................................................................................\n"]}
+    <-- 
{"notify":"Print","command":2,"args":["................................................................................\n"]}
+    <-- 
{"notify":"Print","command":2,"args":["................................................................................\n"]}
+    [...]
+    <-- {"notify":"_Disconnecting"}
+
+A telnet connection allows you to experiment with debug commands by simply
+copy-pasting debug commands to the telnet session.  This is useful even if
+you decide to implement the binary protocol directly.
+
+The debug target used by the proxy can be configured with ``duk_debug.js``
+command line options.
+
+Source search path
+==================
+
+The NodeJS debug client needs to be able to find source code files matching
+code running on the target ("duk" command line).  **The filenames used on the
+target and on the debug client must match exactly**, because e.g. breakpoints
+are targeted based on the 'fileName' property of Function objects.
+
+The search path can be set using the ``--source-dirs`` option given to
+``duk_debug.js``, with the default search paths including only
+``../tests/ecmascript/``.
+
+The default search path means that if a function on the target has fileName
+``foo/bar.js`` it would be loaded from (relative to the duk_debug.js working
+directory, ``debugger/``)::
+
+    ../tests/ecmascript/foo/bar.js
+
+Similarly, if the filesystem contained::
+
+    ../tests/ecmascript/baz/quux.js
+
+the web UI dropdown would show ``baz/quux.js``.  If you selected that file
+and added a breakpoint, the breakpoint fileName sent to the debug target
+would be ``baz/quux.js``.
+
+.. note:: There's much to improve in the search path.  For instance, it'd
+          be nice to add a certain path to search but exclude files based
+          on paths and patterns, etc.
+
+Architecture
+============
+
+::
+
+    +-------------------+
+    | Web browser       |  [debug UI]
+    +-------------------+
+          |
+          | http (port 9092)
+          | socket.io
+          v
+    +-------------------+
+    | duk_debug.js      |  [debug client]
+    +-------------------+
+          |          /\
+          |          ||
+          +----------||---- [example tcp transport] (port 9091)
+          |          ||     (application provides concrete transport)
+          |          ||
+          |          ||---- [debug protocol stream]
+          |          ||     (between debug client and Duktape)
+          |          ||
+    + - - | - - - - -|| - - +
+    :     v          ||     :
+    :  +-------------||-+   :  [target]
+    :  | application || |   :
+    :  +-------------||-+   :
+    :     ^          ||     :
+    :     |          ||     :   [debug API]
+    :     +----------||-------- debug transport callbacks
+    :     |          ||     :   (read, write, peek, read/write flush)
+    :     |          ||     :   implemented by application
+    :     |          \/     :
+    :  +----------------+   :
+    :  | Duktape        |   :
+    :  +----------------+   :
+    + - - - - - - - - - - - +
+
+The debug transport is application specific:
+
+* Duktape command line ("duk") and this debug client use an **example** TCP
+  transport as a concrete example.
+
+* It is entirely up to the application to come up with the most suitable
+  transport for its environment.  Different mechanisms will be needed for
+  Wi-Fi, serial, etc.
+
+The debug protocol running inside the transport is transport independent:
+
+* The debug protocol is documented in ``doc/debugger.rst``.
+
+* This debug client provides further concrete examples and clarifications
+  on how the protocol can be used.
+
+Using a custom transport
+========================
+
+Quite possibly your target device cannot use the example TCP transport and
+you need to implement your own transport.  You'll need to implement your
+custom transport both for the target device and for the debug client.
+
+Target device
+-------------
+
+Implement the debug transport callbacks needed by ``duk_debugger_attach()``.
+
+See ``doc/debugger.rst`` for details and ``examples/debug-trans-socket``
+for example running code for a TCP transport.
+
+Debug client alternative 1: duk_debug.js + custom TCP proxy
+-----------------------------------------------------------
+
+If you don't want to change ``duk_debug.js`` you can implement a TCP proxy
+which accepts a TCP connection from ``duk_debug.js`` and then uses your
+custom transport to talk to the target::
+
+   +--------------+   TCP   +-------+   custom   +--------+
+   | duk_debug.js | ------> | proxy | ---------> | target |
+   +--------------+         +-------+            +--------+
+
+This is a straightforward option and a proxy can be used with other debug
+clients too (perhaps custom scripts talking to the target etc).
+
+You could also use netcat and implement your proxy so that it talks to
+``duk_debug.js`` using stdin/stdout.
+
+Debug client alternative 2: duk_debug.js + custom NodeJS stream
+---------------------------------------------------------------
+
+To make ``duk_debug.js`` use a custom transport you need to:
+
+* Implement your own transport as NodeJS stream.  You can add it directly to
+  ``duk_debug.js`` but it's probably easiest to use a separate module so that
+  the diff to ``duk_debug.js`` stays minimal.
+
+* Change ``duk_debug.js`` to use the custom transport instead of a TCP
+  stream.  Search for "CUSTOMTRANSPORT" in ``duk_debug.js``.
+
+See:
+
+* http://nodejs.org/api/stream.html
+
+* https://github.com/substack/stream-handbook
+
+Debug client alternative 3: custom debug client
+-----------------------------------------------
+
+You can also implement your own debug client and debug UI with support for
+your custom transport.
+
+You'll also need to implement the client part of the Duktape debugger
+protocol.  See ``doc/debugger.rst`` for the specification and ``duk_debug.js``
+for example running code which should illustrate the protocol in more detail.
+
+The JSON debug proxy allows you to implement a debug client without needing
+to implement the Duktape binary debug protocol.  The JSON protocol provides
+a roughly 1:1 mapping to the binary protocol but with an easier syntax.

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/debugger/duk_classnames.yaml
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/debugger/duk_classnames.yaml
 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/debugger/duk_classnames.yaml
new file mode 100644
index 0000000..9fd5098
--- /dev/null
+++ 
b/thirdparty/civetweb-1.9.1/src/third_party/duktape-1.5.2/debugger/duk_classnames.yaml
@@ -0,0 +1,32 @@
+# Must match C header.
+class_names:
+  - unused
+  - Arguments
+  - Array
+  - Boolean
+  - Date
+  - Error
+  - Function
+  - JSON
+  - Math
+  - Number
+  - Object
+  - RegExp
+  - String
+  - global
+  - ObjEnv
+  - DecEnv
+  - Buffer
+  - Pointer
+  - Thread
+  - ArrayBuffer
+  - DataView
+  - Int8Array
+  - Uint8Array
+  - Uint8ClampedArray
+  - Int16Array
+  - Uint16Array
+  - Int32Array
+  - Uint32Array
+  - Float32Array
+  - Float64Array

Reply via email to