#!/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()
