http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/ede68a10/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/config/genconfig.py ---------------------------------------------------------------------- diff --git a/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/config/genconfig.py b/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/config/genconfig.py deleted file mode 100644 index 9c99648..0000000 --- a/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/config/genconfig.py +++ /dev/null @@ -1,1537 +0,0 @@ -#!/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/ede68a10/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/config/genconfig_metadata.tar.gz ---------------------------------------------------------------------- diff --git a/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/config/genconfig_metadata.tar.gz b/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/config/genconfig_metadata.tar.gz deleted file mode 100644 index c34b2ef..0000000 Binary files a/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/config/genconfig_metadata.tar.gz and /dev/null differ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/ede68a10/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/debugger/README.rst ---------------------------------------------------------------------- diff --git a/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/debugger/README.rst b/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/debugger/README.rst deleted file mode 100644 index f60b350..0000000 --- a/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/debugger/README.rst +++ /dev/null @@ -1,384 +0,0 @@ -========================================= -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/ede68a10/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/debugger/duk_classnames.yaml ---------------------------------------------------------------------- diff --git a/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/debugger/duk_classnames.yaml b/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/debugger/duk_classnames.yaml deleted file mode 100644 index 9fd5098..0000000 --- a/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/debugger/duk_classnames.yaml +++ /dev/null @@ -1,32 +0,0 @@ -# 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