Blame src/configgen.py

Packit 1c1d7e
#!/usr/bin/python
Packit 1c1d7e
# python script to generate configoptions.cpp and config.doc from config.xml
Packit 1c1d7e
#
Packit 1c1d7e
# Copyright (C) 1997-2015 by Dimitri van Heesch.
Packit 1c1d7e
#
Packit 1c1d7e
# Permission to use, copy, modify, and distribute this software and its
Packit 1c1d7e
# documentation under the terms of the GNU General Public License is hereby
Packit 1c1d7e
# granted. No representations are made about the suitability of this software
Packit 1c1d7e
# for any purpose. It is provided "as is" without express or implied warranty.
Packit 1c1d7e
# See the GNU General Public License for more details.
Packit 1c1d7e
#
Packit 1c1d7e
# Documents produced by Doxygen are derivative works derived from the
Packit 1c1d7e
# input used in their production; they are not affected by this license.
Packit 1c1d7e
#
Packit 1c1d7e
import xml.dom.minidom
Packit 1c1d7e
import sys
Packit 1c1d7e
import re
Packit 1c1d7e
import textwrap
Packit 1c1d7e
from xml.dom import minidom, Node
Packit 1c1d7e
Packit 1c1d7e
def transformDocs(doc):
Packit 1c1d7e
	# join lines, unless it is an empty line
Packit 1c1d7e
	# remove doxygen layout constructs
Packit 1c1d7e
	doc = doc.strip()
Packit 1c1d7e
	doc = doc.replace("\n", " ")
Packit 1c1d7e
	doc = doc.replace("\r", " ")
Packit 1c1d7e
	doc = doc.replace("\t", " ")
Packit 1c1d7e
	doc = doc.replace("\\&", "&")
Packit 1c1d7e
	doc = doc.replace("(\\c ", "(")
Packit 1c1d7e
	doc = doc.replace("\\c ", " ")
Packit 1c1d7e
	doc = doc.replace("\\b ", " ")
Packit 1c1d7e
	doc = doc.replace("\\e ", " ")
Packit 1c1d7e
	doc = doc.replace("\\$", "$")
Packit 1c1d7e
	doc = doc.replace("\\#include ", "#include ")
Packit 1c1d7e
	doc = doc.replace("\\#undef ", "#undef ")
Packit 1c1d7e
	doc = doc.replace("-# ", "\n - ")
Packit 1c1d7e
	doc = doc.replace(" - ", "\n - ")
Packit 1c1d7e
	doc = doc.replace("\\sa", "\nSee also: ")
Packit 1c1d7e
	doc = doc.replace("\\par", "\n")
Packit 1c1d7e
	doc = doc.replace("@note", "\nNote:")
Packit 1c1d7e
	doc = doc.replace("\\note", "\nNote:")
Packit 1c1d7e
	doc = doc.replace("\\verbatim", "\n")
Packit 1c1d7e
	doc = doc.replace("\\endverbatim", "\n")
Packit 1c1d7e
	doc = doc.replace("", "")
Packit 1c1d7e
	doc = doc.replace("", "")
Packit 1c1d7e
	doc = doc.replace("`", "")
Packit 1c1d7e
	doc = doc.replace("\\<", "<")
Packit 1c1d7e
	doc = doc.replace("\\>", ">")
Packit 1c1d7e
	doc = doc.replace("\\@", "@")
Packit 1c1d7e
	doc = doc.replace("\\\\", "\\")
Packit 1c1d7e
	# \ref name "description" -> description
Packit 1c1d7e
	doc = re.sub('\\\\ref +[^ ]* +"([^"]*)"', '\\1', doc)
Packit 1c1d7e
	# \ref specials
Packit 1c1d7e
	# \ref <key> -> description
Packit 1c1d7e
	doc = re.sub('\\\\ref +doxygen_usage', '"Doxygen usage"', doc)
Packit 1c1d7e
	doc = re.sub('\\\\ref +extsearch', '"External Indexing and Searching"',
Packit 1c1d7e
				 doc)
Packit 1c1d7e
	doc = re.sub('\\\\ref +external', '"Linking to external documentation"',
Packit 1c1d7e
				 doc)
Packit 1c1d7e
	# fallback for not handled
Packit 1c1d7e
	doc = re.sub('\\\\ref', '', doc)
Packit 1c1d7e
	#description -> description (see: address)
Packit 1c1d7e
	doc = re.sub('([^<]*)', '\\2 (see: \\1)', doc)
Packit 1c1d7e
	# LaTeX name as formula -> LaTeX
Packit 1c1d7e
	doc = doc.replace("\\f$\\mbox{\\LaTeX}\\f$", "LaTeX")
Packit 1c1d7e
	# Other formula's (now just 2) so explicitly mentioned.
Packit 1c1d7e
	doc = doc.replace("\\f$2^{(16+\\mbox{LOOKUP\\_CACHE\\_SIZE})}\\f$",
Packit 1c1d7e
					  "2^(16+LOOKUP_CACHE_SIZE)")
Packit 1c1d7e
	doc = doc.replace("\\f$2^{16} = 65536\\f$", "2^16=65536")
Packit 1c1d7e
	# remove consecutive spaces
Packit 1c1d7e
	doc = re.sub(" +", " ", doc)
Packit 1c1d7e
	# a dirty trick to get an extra empty line in Doxyfile documentation.
Packit 1c1d7e
	# 
will be removed later on again, we need it here otherwise splitlines
Packit 1c1d7e
	# will filter the extra line.
Packit 1c1d7e
	doc = doc.replace("
", "\n
\n")
Packit 1c1d7e
	# a dirty trick to go to the next line in Doxyfile documentation.
Packit 1c1d7e
	# 
will be removed later on again, we need it here otherwise splitlines
Packit 1c1d7e
	# will filter the line break.
Packit 1c1d7e
	doc = doc.replace("
", "\n
\n")
Packit 1c1d7e
	#
Packit 1c1d7e
	doc = doc.splitlines()
Packit 1c1d7e
	split_doc = []
Packit 1c1d7e
	for line in doc:
Packit 1c1d7e
		split_doc += textwrap.wrap(line, 78)
Packit 1c1d7e
	# replace \ by \\, replace " by \", and '  ' by a newline with end string
Packit 1c1d7e
	# and start string at next line
Packit 1c1d7e
	docC = []
Packit 1c1d7e
	for line in split_doc:
Packit 1c1d7e
		if (line.strip() != "
"):
Packit 1c1d7e
			docC.append(line.strip().replace('\\', '\\\\').
Packit 1c1d7e
					replace('"', '\\"').replace("
", ""))
Packit 1c1d7e
	return docC
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def collectValues(node):
Packit 1c1d7e
	values = []
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if (n.nodeName == "value"):
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if n.getAttribute('name') != "":
Packit 1c1d7e
					if n.getAttribute('show_docu') != "NO":
Packit 1c1d7e
						name = "" + n.getAttribute('name') + ""
Packit 1c1d7e
						desc = n.getAttribute('desc')
Packit 1c1d7e
						if (desc != ""):
Packit 1c1d7e
							name += " " + desc
Packit 1c1d7e
						values.append(name)
Packit 1c1d7e
	return values
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def addValues(var, node):
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if (n.nodeName == "value"):
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				name = n.getAttribute('name')
Packit 1c1d7e
				print("  %s->addValue(\"%s\");" % (var, name))
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def parseHeader(node,objName):
Packit 1c1d7e
	doc = ""
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
			if (n.nodeName == "docs"):
Packit 1c1d7e
				if (n.getAttribute('doxyfile') != "0"):
Packit 1c1d7e
					doc += parseDocs(n)
Packit 1c1d7e
	docC = transformDocs(doc)
Packit 1c1d7e
	print("  %s->setHeader(" % (objName))
Packit 1c1d7e
	rng = len(docC)
Packit 1c1d7e
	for i in range(rng):
Packit 1c1d7e
		line = docC[i]
Packit 1c1d7e
		if i != rng - 1:  # since we go from 0 to rng-1
Packit 1c1d7e
			print("              \"%s\\n\"" % (line))
Packit 1c1d7e
		else:
Packit 1c1d7e
			print("              \"%s\"" % (line))
Packit 1c1d7e
	print("             );")
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def prepCDocs(node):
Packit 1c1d7e
	type = node.getAttribute('type')
Packit 1c1d7e
	format = node.getAttribute('format')
Packit 1c1d7e
	defval = node.getAttribute('defval')
Packit 1c1d7e
	adefval = node.getAttribute('altdefval')
Packit 1c1d7e
	doc = "";
Packit 1c1d7e
	if (type != 'obsolete'):
Packit 1c1d7e
		for n in node.childNodes:
Packit 1c1d7e
			if (n.nodeName == "docs"):
Packit 1c1d7e
				if (n.getAttribute('doxyfile') != "0"):
Packit 1c1d7e
					if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
						doc += parseDocs(n)
Packit 1c1d7e
		if (type == 'enum'):
Packit 1c1d7e
			values = collectValues(node)
Packit 1c1d7e
			doc += "
Possible values are: "
Packit 1c1d7e
			rng = len(values)
Packit 1c1d7e
			for i in range(rng):
Packit 1c1d7e
				val = values[i]
Packit 1c1d7e
				if i == rng - 2:
Packit 1c1d7e
					doc += "%s and " % (val)
Packit 1c1d7e
				elif i == rng - 1:
Packit 1c1d7e
					doc += "%s." % (val)
Packit 1c1d7e
				else:
Packit 1c1d7e
					doc += "%s, " % (val)
Packit 1c1d7e
			if (defval != ""):
Packit 1c1d7e
				doc += "
The default value is: %s." % (defval)
Packit 1c1d7e
		elif (type == 'int'):
Packit 1c1d7e
			minval = node.getAttribute('minval')
Packit 1c1d7e
			maxval = node.getAttribute('maxval')
Packit 1c1d7e
			doc += "
%s: %s, %s: %s, %s: %s." % (" Minimum value", minval,
Packit 1c1d7e
					 "maximum value", maxval,
Packit 1c1d7e
					 "default value", defval)
Packit 1c1d7e
		elif (type == 'bool'):
Packit 1c1d7e
			if (node.hasAttribute('altdefval')):
Packit 1c1d7e
			  doc += "
%s: %s." % ("The default value is", "system dependent")
Packit 1c1d7e
			else:
Packit 1c1d7e
			  doc += "
%s: %s." % ("The default value is", "YES" if (defval == "1") else "NO")
Packit 1c1d7e
		elif (type == 'list'):
Packit 1c1d7e
			if format == 'string':
Packit 1c1d7e
				values = collectValues(node)
Packit 1c1d7e
				rng = len(values)
Packit 1c1d7e
				for i in range(rng):
Packit 1c1d7e
					val = values[i]
Packit 1c1d7e
					if i == rng - 2:
Packit 1c1d7e
						doc += "%s and " % (val)
Packit 1c1d7e
					elif i == rng - 1:
Packit 1c1d7e
						doc += "%s." % (val)
Packit 1c1d7e
					else:
Packit 1c1d7e
						doc += "%s, " % (val)
Packit 1c1d7e
		elif (type == 'string'):
Packit 1c1d7e
			if format == 'dir':
Packit 1c1d7e
				if defval != '':
Packit 1c1d7e
					doc += "
The default directory is: %s." % (
Packit 1c1d7e
						defval)
Packit 1c1d7e
			elif format == 'file':
Packit 1c1d7e
				abspath = node.getAttribute('abspath')
Packit 1c1d7e
				if defval != '':
Packit 1c1d7e
					if abspath != '1':
Packit 1c1d7e
						doc += "
The default file is: %s." % (
Packit 1c1d7e
							defval)
Packit 1c1d7e
					else:
Packit 1c1d7e
						doc += "
%s: %s%s%s." % (
Packit 1c1d7e
							"The default file (with absolute path) is",
Packit 1c1d7e
							"",defval,"")
Packit 1c1d7e
				else:
Packit 1c1d7e
					if abspath == '1':
Packit 1c1d7e
						doc += "
The file has to be specified with full path."
Packit 1c1d7e
			elif format =='image':
Packit 1c1d7e
				abspath = node.getAttribute('abspath')
Packit 1c1d7e
				if defval != '':
Packit 1c1d7e
					if abspath != '1':
Packit 1c1d7e
						doc += "
The default image is: %s." % (
Packit 1c1d7e
							defval)
Packit 1c1d7e
					else:
Packit 1c1d7e
						doc += "
%s: %s%s%s." % (
Packit 1c1d7e
							"The default image (with absolute path) is",
Packit 1c1d7e
							"",defval,"")
Packit 1c1d7e
				else:
Packit 1c1d7e
					if abspath == '1':
Packit 1c1d7e
						doc += "
The image has to be specified with full path."
Packit 1c1d7e
			else: # format == 'string':
Packit 1c1d7e
				if defval != '':
Packit 1c1d7e
					doc += "
The default value is: %s." % (
Packit 1c1d7e
						defval)
Packit 1c1d7e
		# depends handling
Packit 1c1d7e
		if (node.hasAttribute('depends')):
Packit 1c1d7e
			depends = node.getAttribute('depends')
Packit 1c1d7e
			doc += "
%s \\ref cfg_%s \"%s\" is set to \\c YES." % (
Packit 1c1d7e
				"This tag requires that the tag", depends.lower(), depends.upper())
Packit 1c1d7e
Packit 1c1d7e
	docC = transformDocs(doc)
Packit 1c1d7e
	return docC;
Packit 1c1d7e
Packit 1c1d7e
def parseOption(node):
Packit 1c1d7e
	# Handling part for Doxyfile
Packit 1c1d7e
	name = node.getAttribute('id')
Packit 1c1d7e
	type = node.getAttribute('type')
Packit 1c1d7e
	format = node.getAttribute('format')
Packit 1c1d7e
	defval = node.getAttribute('defval')
Packit 1c1d7e
	adefval = node.getAttribute('altdefval')
Packit 1c1d7e
	depends = node.getAttribute('depends')
Packit 1c1d7e
	setting = node.getAttribute('setting')
Packit 1c1d7e
	docC = prepCDocs(node);
Packit 1c1d7e
	if len(setting) > 0:
Packit 1c1d7e
		print("#if %s" % (setting))
Packit 1c1d7e
	print("  //----")
Packit 1c1d7e
	if type == 'bool':
Packit 1c1d7e
		if len(adefval) > 0:
Packit 1c1d7e
			enabled = adefval
Packit 1c1d7e
		elif defval == '1':
Packit 1c1d7e
			enabled = "TRUE"
Packit 1c1d7e
		else:
Packit 1c1d7e
			enabled = "FALSE"
Packit 1c1d7e
		print("  cb = cfg->addBool(")
Packit 1c1d7e
		print("             \"%s\"," % (name))
Packit 1c1d7e
		rng = len(docC)
Packit 1c1d7e
		for i in range(rng):
Packit 1c1d7e
			line = docC[i]
Packit 1c1d7e
			if i != rng - 1:  # since we go from 0 to rng-1
Packit 1c1d7e
				print("              \"%s\\n\"" % (line))
Packit 1c1d7e
			else:
Packit 1c1d7e
				print("              \"%s\"," % (line))
Packit 1c1d7e
		print("              %s" % (enabled))
Packit 1c1d7e
		print("             );")
Packit 1c1d7e
		if depends != '':
Packit 1c1d7e
			print("  cb->addDependency(\"%s\");" % (depends))
Packit 1c1d7e
	elif type == 'string':
Packit 1c1d7e
		print("  cs = cfg->addString(")
Packit 1c1d7e
		print("              \"%s\"," % (name))
Packit 1c1d7e
		rng = len(docC)
Packit 1c1d7e
		for i in range(rng):
Packit 1c1d7e
			line = docC[i]
Packit 1c1d7e
			if i != rng - 1:  # since we go from 0 to rng-1
Packit 1c1d7e
				print("              \"%s\\n\"" % (line))
Packit 1c1d7e
			else:
Packit 1c1d7e
				print("              \"%s\"" % (line))
Packit 1c1d7e
		print("             );")
Packit 1c1d7e
		if defval != '':
Packit 1c1d7e
			print("  cs->setDefaultValue(\"%s\");" % (defval))
Packit 1c1d7e
		if format == 'file':
Packit 1c1d7e
			print("  cs->setWidgetType(ConfigString::File);")
Packit 1c1d7e
		elif format == 'image':
Packit 1c1d7e
			print("  cs->setWidgetType(ConfigString::Image);")
Packit 1c1d7e
		elif format == 'dir':
Packit 1c1d7e
			print("  cs->setWidgetType(ConfigString::Dir);")
Packit 1c1d7e
		if depends != '':
Packit 1c1d7e
			print("  cs->addDependency(\"%s\");" % (depends))
Packit 1c1d7e
	elif type == 'enum':
Packit 1c1d7e
		print("  ce = cfg->addEnum(")
Packit 1c1d7e
		print("              \"%s\"," % (name))
Packit 1c1d7e
		rng = len(docC)
Packit 1c1d7e
		for i in range(rng):
Packit 1c1d7e
			line = docC[i]
Packit 1c1d7e
			if i != rng - 1:  # since we go from 0 to rng-1
Packit 1c1d7e
				print("              \"%s\\n\"" % (line))
Packit 1c1d7e
			else:
Packit 1c1d7e
				print("              \"%s\"," % (line))
Packit 1c1d7e
		print("              \"%s\"" % (defval))
Packit 1c1d7e
		print("             );")
Packit 1c1d7e
		addValues("ce", node)
Packit 1c1d7e
		if depends != '':
Packit 1c1d7e
			print("  ce->addDependency(\"%s\");" % (depends))
Packit 1c1d7e
	elif type == 'int':
Packit 1c1d7e
		minval = node.getAttribute('minval')
Packit 1c1d7e
		maxval = node.getAttribute('maxval')
Packit 1c1d7e
		print("  ci = cfg->addInt(")
Packit 1c1d7e
		print("              \"%s\"," % (name))
Packit 1c1d7e
		rng = len(docC)
Packit 1c1d7e
		for i in range(rng):
Packit 1c1d7e
			line = docC[i]
Packit 1c1d7e
			if i != rng - 1:  # since we go from 0 to rng-1
Packit 1c1d7e
				print("              \"%s\\n\"" % (line))
Packit 1c1d7e
			else:
Packit 1c1d7e
				print("              \"%s\"," % (line))
Packit 1c1d7e
		print("              %s,%s,%s" % (minval, maxval, defval))
Packit 1c1d7e
		print("             );")
Packit 1c1d7e
		if depends != '':
Packit 1c1d7e
			print("  ci->addDependency(\"%s\");" % (depends))
Packit 1c1d7e
	elif type == 'list':
Packit 1c1d7e
		print("  cl = cfg->addList(")
Packit 1c1d7e
		print("              \"%s\"," % (name))
Packit 1c1d7e
		rng = len(docC)
Packit 1c1d7e
		for i in range(rng):
Packit 1c1d7e
			line = docC[i]
Packit 1c1d7e
			if i != rng - 1:  # since we go from 0 to rng-1
Packit 1c1d7e
				print("              \"%s\\n\"" % (line))
Packit 1c1d7e
			else:
Packit 1c1d7e
				print("              \"%s\"" % (line))
Packit 1c1d7e
		print("             );")
Packit 1c1d7e
		addValues("cl", node)
Packit 1c1d7e
		if depends != '':
Packit 1c1d7e
			print("  cl->addDependency(\"%s\");" % (depends))
Packit 1c1d7e
		if format == 'file':
Packit 1c1d7e
			print("  cl->setWidgetType(ConfigList::File);")
Packit 1c1d7e
		elif format == 'dir':
Packit 1c1d7e
			print("  cl->setWidgetType(ConfigList::Dir);")
Packit 1c1d7e
		elif format == 'filedir':
Packit 1c1d7e
			print("  cl->setWidgetType(ConfigList::FileAndDir);")
Packit 1c1d7e
	elif type == 'obsolete':
Packit 1c1d7e
		print("  cfg->addObsolete(\"%s\");" % (name))
Packit 1c1d7e
	if len(setting) > 0:
Packit 1c1d7e
		print("#else")
Packit 1c1d7e
		print("  cfg->addDisabled(\"%s\");" % (name))
Packit 1c1d7e
		print("#endif")
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def parseGroups(node):
Packit 1c1d7e
	name = node.getAttribute('name')
Packit 1c1d7e
	doc = node.getAttribute('docs')
Packit 1c1d7e
	print("%s%s" % ("  //-----------------------------------------",
Packit 1c1d7e
					"----------------------------------"))
Packit 1c1d7e
	print("  cfg->addInfo(\"%s\",\"%s\");" % (name, doc))
Packit 1c1d7e
	print("%s%s" % ("  //-----------------------------------------",
Packit 1c1d7e
					"----------------------------------"))
Packit 1c1d7e
	print("")
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
			parseOption(n)
Packit 1c1d7e
Packit 1c1d7e
def parseGroupMap(node):
Packit 1c1d7e
	map = { 'bool':'bool', 'string':'QCString', 'enum':'QCString', 'int':'int', 'list':'QStrList' }
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
			setting = n.getAttribute('setting')
Packit 1c1d7e
			if len(setting) > 0:
Packit 1c1d7e
				print("#if %s" % (setting))
Packit 1c1d7e
			type = n.getAttribute('type')
Packit 1c1d7e
			name = n.getAttribute('id')
Packit 1c1d7e
			if type in map:
Packit 1c1d7e
				print("    %-8s %s;" % (map[type],name))
Packit 1c1d7e
			if len(setting) > 0:
Packit 1c1d7e
				print("#endif")
Packit 1c1d7e
Packit 1c1d7e
def parseGroupInit(node):
Packit 1c1d7e
	map = { 'bool':'Bool', 'string':'String', 'enum':'Enum', 'int':'Int', 'list':'List' }
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
			setting = n.getAttribute('setting')
Packit 1c1d7e
			if len(setting) > 0:
Packit 1c1d7e
				print("#if %s" % (setting))
Packit 1c1d7e
			type = n.getAttribute('type')
Packit 1c1d7e
			name = n.getAttribute('id')
Packit 1c1d7e
			if type in map:
Packit 1c1d7e
				print("  %-25s = ConfigImpl::instance()->get%s(__FILE__,__LINE__,\"%s\");" % (name,map[type],name))
Packit 1c1d7e
			if len(setting) > 0:
Packit 1c1d7e
				print("#endif")
Packit 1c1d7e
Packit 1c1d7e
def parseGroupMapInit(node):
Packit 1c1d7e
	map = { 'bool':'Bool', 'string':'String', 'enum':'String', 'int':'Int', 'list':'List' }
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
			setting = n.getAttribute('setting')
Packit 1c1d7e
			if len(setting) > 0:
Packit 1c1d7e
				print("#if %s" % (setting))
Packit 1c1d7e
			type = n.getAttribute('type')
Packit 1c1d7e
			name = n.getAttribute('id')
Packit 1c1d7e
			if type in map:
Packit 1c1d7e
				print("  m_map.insert(\"%s\",new Info%s(&ConfigValues::%s));" % (name,map[type],name))
Packit 1c1d7e
			if len(setting) > 0:
Packit 1c1d7e
				print("#endif")
Packit 1c1d7e
Packit 1c1d7e
def parseGroupCDocs(node):
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
			type = n.getAttribute('type')
Packit 1c1d7e
			name = n.getAttribute('id')
Packit 1c1d7e
			docC = prepCDocs(n);
Packit 1c1d7e
			if type != 'obsolete':
Packit 1c1d7e
				print("  doc->add(")
Packit 1c1d7e
				print("              \"%s\"," % (name))
Packit 1c1d7e
				rng = len(docC)
Packit 1c1d7e
				for i in range(rng):
Packit 1c1d7e
					line = docC[i]
Packit 1c1d7e
					if i != rng - 1:  # since we go from 0 to rng-1
Packit 1c1d7e
						print("              \"%s\\n\"" % (line))
Packit 1c1d7e
					else:
Packit 1c1d7e
						print("              \"%s\"" % (line))
Packit 1c1d7e
				print("          );")
Packit 1c1d7e
Packit 1c1d7e
def parseOptionDoc(node, first):
Packit 1c1d7e
	# Handling part for documentation
Packit 1c1d7e
	name = node.getAttribute('id')
Packit 1c1d7e
	type = node.getAttribute('type')
Packit 1c1d7e
	format = node.getAttribute('format')
Packit 1c1d7e
	defval = node.getAttribute('defval')
Packit 1c1d7e
	adefval = node.getAttribute('altdefval')
Packit 1c1d7e
	depends = node.getAttribute('depends')
Packit 1c1d7e
	setting = node.getAttribute('setting')
Packit 1c1d7e
	doc = ""
Packit 1c1d7e
	if (type != 'obsolete'):
Packit 1c1d7e
		for n in node.childNodes:
Packit 1c1d7e
			if (n.nodeName == "docs"):
Packit 1c1d7e
				if (n.getAttribute('documentation') != "0"):
Packit 1c1d7e
					if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
						doc += parseDocs(n)
Packit 1c1d7e
		if (first):
Packit 1c1d7e
			print(" \\anchor cfg_%s" % (name.lower()))
Packit 1c1d7e
			print("
")
Packit 1c1d7e
			print("")
Packit 1c1d7e
			print("
\\c %s
" % (name))
Packit 1c1d7e
		else:
Packit 1c1d7e
			print(" \\anchor cfg_%s" % (name.lower()))
Packit 1c1d7e
			print("
\\c %s
" % (name))
Packit 1c1d7e
		print(" \\addindex %s" % (name))
Packit 1c1d7e
		print(doc)
Packit 1c1d7e
		if (type == 'enum'):
Packit 1c1d7e
			values = collectValues(node)
Packit 1c1d7e
			print("")
Packit 1c1d7e
			print("Possible values are: ")
Packit 1c1d7e
			rng = len(values)
Packit 1c1d7e
			for i in range(rng):
Packit 1c1d7e
				val = values[i]
Packit 1c1d7e
				if i == rng - 2:
Packit 1c1d7e
					print("%s and " % (val))
Packit 1c1d7e
				elif i == rng - 1:
Packit 1c1d7e
					print("%s." % (val))
Packit 1c1d7e
				else:
Packit 1c1d7e
					print("%s, " % (val))
Packit 1c1d7e
			if (defval != ""):
Packit 1c1d7e
				print("")
Packit 1c1d7e
				print("")
Packit 1c1d7e
				print("The default value is: %s." % (defval))
Packit 1c1d7e
			print("")
Packit 1c1d7e
		elif (type == 'int'):
Packit 1c1d7e
			minval = node.getAttribute('minval')
Packit 1c1d7e
			maxval = node.getAttribute('maxval')
Packit 1c1d7e
			print("")
Packit 1c1d7e
			print("")
Packit 1c1d7e
			print("%s: %s%s%s, %s: %s%s%s, %s: %s%s%s." % (
Packit 1c1d7e
					 " Minimum value", "", minval, "", 
Packit 1c1d7e
					 "maximum value", "", maxval, "",
Packit 1c1d7e
					 "default value", "", defval, ""))
Packit 1c1d7e
			print("")
Packit 1c1d7e
		elif (type == 'bool'):
Packit 1c1d7e
			print("")
Packit 1c1d7e
			print("")
Packit 1c1d7e
			if (node.hasAttribute('altdefval')):
Packit 1c1d7e
				print("The default value is: system dependent.")
Packit 1c1d7e
			else:
Packit 1c1d7e
				print("The default value is: %s." % (
Packit 1c1d7e
					"YES" if (defval == "1") else "NO"))
Packit 1c1d7e
			print("")
Packit 1c1d7e
		elif (type == 'list'):
Packit 1c1d7e
			if format == 'string':
Packit 1c1d7e
				values = collectValues(node)
Packit 1c1d7e
				rng = len(values)
Packit 1c1d7e
				for i in range(rng):
Packit 1c1d7e
					val = values[i]
Packit 1c1d7e
					if i == rng - 2:
Packit 1c1d7e
						print("%s and " % (val))
Packit 1c1d7e
					elif i == rng - 1:
Packit 1c1d7e
						print("%s." % (val))
Packit 1c1d7e
					else:
Packit 1c1d7e
						print("%s, " % (val))
Packit 1c1d7e
			print("")
Packit 1c1d7e
		elif (type == 'string'):
Packit 1c1d7e
			if format == 'dir':
Packit 1c1d7e
				if defval != '':
Packit 1c1d7e
					print("")
Packit 1c1d7e
					print("The default directory is: %s." % (
Packit 1c1d7e
						defval))
Packit 1c1d7e
			elif format == 'file':
Packit 1c1d7e
				abspath = node.getAttribute('abspath')
Packit 1c1d7e
				if defval != '':
Packit 1c1d7e
					print("")
Packit 1c1d7e
					if abspath != '1':
Packit 1c1d7e
						print("The default file is: %s." % (
Packit 1c1d7e
							defval))
Packit 1c1d7e
					else:
Packit 1c1d7e
						print("%s: %s%s%s." % (
Packit 1c1d7e
							"The default file (with absolute path) is",
Packit 1c1d7e
							"",defval,""))
Packit 1c1d7e
				else:
Packit 1c1d7e
					if abspath == '1':
Packit 1c1d7e
						print("")
Packit 1c1d7e
						print("The file has to be specified with full path.")
Packit 1c1d7e
			elif format =='image':
Packit 1c1d7e
				abspath = node.getAttribute('abspath')
Packit 1c1d7e
				if defval != '':
Packit 1c1d7e
					print("")
Packit 1c1d7e
					if abspath != '1':
Packit 1c1d7e
						print("The default image is: %s." % (
Packit 1c1d7e
							defval))
Packit 1c1d7e
					else:
Packit 1c1d7e
						print("%s: %s%s%s." % (
Packit 1c1d7e
							"The default image (with absolute path) is",
Packit 1c1d7e
							"",defval,""))
Packit 1c1d7e
				else:
Packit 1c1d7e
					if abspath == '1':
Packit 1c1d7e
						print("")
Packit 1c1d7e
						print("The image has to be specified with full path.")
Packit 1c1d7e
			else: # format == 'string':
Packit 1c1d7e
				if defval != '':
Packit 1c1d7e
					print("")
Packit 1c1d7e
					print("The default value is: %s." % (
Packit 1c1d7e
						defval))
Packit 1c1d7e
			print("")
Packit 1c1d7e
		# depends handling
Packit 1c1d7e
		if (node.hasAttribute('depends')):
Packit 1c1d7e
			depends = node.getAttribute('depends')
Packit 1c1d7e
			print("")
Packit 1c1d7e
			print("%s \\ref cfg_%s \"%s\" is set to \\c YES." % (
Packit 1c1d7e
				"This tag requires that the tag", depends.lower(), depends.upper()))
Packit 1c1d7e
		return False
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def parseGroupsDoc(node):
Packit 1c1d7e
	name = node.getAttribute('name')
Packit 1c1d7e
	doc = node.getAttribute('docs')
Packit 1c1d7e
	print("\section config_%s %s" % (name.lower(), doc))
Packit 1c1d7e
	# Start of list has been moved to the first option for better
Packit 1c1d7e
	# anchor placement
Packit 1c1d7e
	#  print "
"
Packit 1c1d7e
	#  print ""
Packit 1c1d7e
	first = True
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
			first = parseOptionDoc(n, first)
Packit 1c1d7e
	if (not first):
Packit 1c1d7e
		print("")
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def parseGroupsList(node, commandsList):
Packit 1c1d7e
	list = ()
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
			type = n.getAttribute('type')
Packit 1c1d7e
			if type != 'obsolete':
Packit 1c1d7e
				commandsList = commandsList + (n.getAttribute('id'),)
Packit 1c1d7e
	return commandsList
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def parseDocs(node):
Packit 1c1d7e
	doc = ""
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.TEXT_NODE:
Packit 1c1d7e
			doc += n.nodeValue.strip()
Packit 1c1d7e
		if n.nodeType == Node.CDATA_SECTION_NODE:
Packit 1c1d7e
			doc += n.nodeValue.rstrip("\r\n ").lstrip("\r\n")
Packit 1c1d7e
	#doc += "
"
Packit 1c1d7e
	return doc
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def parseHeaderDoc(node):
Packit 1c1d7e
	doc = ""
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
			if (n.nodeName == "docs"):
Packit 1c1d7e
				if (n.getAttribute('documentation') != "0"):
Packit 1c1d7e
					doc += parseDocs(n)
Packit 1c1d7e
	print(doc)
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def parseFooterDoc(node):
Packit 1c1d7e
	doc = ""
Packit 1c1d7e
	for n in node.childNodes:
Packit 1c1d7e
		if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
			if (n.nodeName == "docs"):
Packit 1c1d7e
				if (n.getAttribute('documentation') != "0"):
Packit 1c1d7e
					doc += parseDocs(n)
Packit 1c1d7e
	print(doc)
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def main():
Packit 1c1d7e
	if len(sys.argv)<3 or (not sys.argv[1] in ['-doc','-cpp','-wiz','-maph','-maps']):
Packit 1c1d7e
		sys.exit('Usage: %s -doc|-cpp|-wiz|-maph|-maps config.xml' % sys.argv[0])
Packit 1c1d7e
	try:
Packit 1c1d7e
		doc = xml.dom.minidom.parse(sys.argv[2])
Packit 1c1d7e
	except Exception as inst:
Packit 1c1d7e
		sys.stdout = sys.stderr
Packit 1c1d7e
		print("")
Packit 1c1d7e
		print(inst)
Packit 1c1d7e
		print("")
Packit 1c1d7e
		sys.exit(1)
Packit 1c1d7e
	elem = doc.documentElement
Packit 1c1d7e
	if (sys.argv[1] == "-doc"):
Packit 1c1d7e
		print("/* WARNING: This file is generated!")
Packit 1c1d7e
		print(" * Do not edit this file, but edit config.xml instead and run")
Packit 1c1d7e
		print(" * python configgen.py -doc config.xml to regenerate this file!")
Packit 1c1d7e
		print(" */")
Packit 1c1d7e
		# process header
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "header"):
Packit 1c1d7e
					parseHeaderDoc(n)
Packit 1c1d7e
		# generate list with all commands
Packit 1c1d7e
		commandsList = ()
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "group"):
Packit 1c1d7e
					commandsList = parseGroupsList(n, commandsList)
Packit 1c1d7e
		print("\\secreflist")
Packit 1c1d7e
		for x in sorted(commandsList):
Packit 1c1d7e
			print("\\refitem cfg_%s %s" % (x.lower(), x))
Packit 1c1d7e
		print("\\endsecreflist")
Packit 1c1d7e
		# process groups and options
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "group"):
Packit 1c1d7e
					parseGroupsDoc(n)
Packit 1c1d7e
		# process footers
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "footer"):
Packit 1c1d7e
					parseFooterDoc(n)
Packit 1c1d7e
	elif (sys.argv[1] == "-maph"):
Packit 1c1d7e
		print("/* WARNING: This file is generated!")
Packit 1c1d7e
		print(" * Do not edit this file, but edit config.xml instead and run")
Packit 1c1d7e
		print(" * python configgen.py -map config.xml to regenerate this file!")
Packit 1c1d7e
		print(" */")
Packit 1c1d7e
		print("#ifndef CONFIGVALUES_H")
Packit 1c1d7e
		print("#define CONFIGVALUES_H")
Packit 1c1d7e
		print("")
Packit 1c1d7e
		print("#include <qdict.h>")
Packit 1c1d7e
		print("#include <qstrlist.h>")
Packit 1c1d7e
		print("#include <qcstring.h>")
Packit 1c1d7e
		print("#include \"settings.h\"")
Packit 1c1d7e
		print("")
Packit 1c1d7e
		print("class ConfigValues")
Packit 1c1d7e
		print("{")
Packit 1c1d7e
		print("  public:")
Packit 1c1d7e
		print("    static ConfigValues &instance() { static ConfigValues theInstance; return theInstance; }")
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "group"):
Packit 1c1d7e
					parseGroupMap(n)
Packit 1c1d7e
		print("    void init();")
Packit 1c1d7e
		print("    struct Info")
Packit 1c1d7e
		print("    {")
Packit 1c1d7e
		print("      enum Type { Bool, Int, String, List, Unknown };")
Packit 1c1d7e
		print("      Info(Type t) : type(t) {}")
Packit 1c1d7e
		print("      virtual ~Info() {}")
Packit 1c1d7e
		print("      Type type;")
Packit 1c1d7e
		print("    };")
Packit 1c1d7e
		print("    struct InfoBool : public Info")
Packit 1c1d7e
		print("    {")
Packit 1c1d7e
		print("      InfoBool(bool ConfigValues::*ptm) : Info(Info::Bool), item(ptm) {}")
Packit 1c1d7e
		print("      bool ConfigValues::*item;")
Packit 1c1d7e
		print("    };")
Packit 1c1d7e
		print("    struct InfoInt : public Info")
Packit 1c1d7e
		print("    {")
Packit 1c1d7e
		print("      InfoInt(int ConfigValues::*ptm) : Info(Info::Int), item(ptm) {}")
Packit 1c1d7e
		print("      int ConfigValues::*item;")
Packit 1c1d7e
		print("    };")
Packit 1c1d7e
		print("    struct InfoString : public Info")
Packit 1c1d7e
		print("    {")
Packit 1c1d7e
		print("      InfoString(QCString ConfigValues::*ptm) : Info(Info::String), item(ptm) {}")
Packit 1c1d7e
		print("      QCString ConfigValues::*item;")
Packit 1c1d7e
		print("    };")
Packit 1c1d7e
		print("    struct InfoList : public Info")
Packit 1c1d7e
		print("    {")
Packit 1c1d7e
		print("      InfoList(QStrList ConfigValues::*ptm) : Info(Info::List), item(ptm) {}")
Packit 1c1d7e
		print("      QStrList ConfigValues::*item;")
Packit 1c1d7e
		print("    };")
Packit 1c1d7e
		print("    const Info *get(const char *tag) const")
Packit 1c1d7e
		print("    {")
Packit 1c1d7e
		print("      return m_map.find(tag);")
Packit 1c1d7e
		print("    }")
Packit 1c1d7e
		print("  private:")
Packit 1c1d7e
		print("    ConfigValues();")
Packit 1c1d7e
		print("    QDict<Info> m_map;")
Packit 1c1d7e
		print("};")
Packit 1c1d7e
		print("")
Packit 1c1d7e
		print("#endif")
Packit 1c1d7e
	elif (sys.argv[1] == "-maps"):
Packit 1c1d7e
		print("/* WARNING: This file is generated!")
Packit 1c1d7e
		print(" * Do not edit this file, but edit config.xml instead and run")
Packit 1c1d7e
		print(" * python configgen.py -maps config.xml to regenerate this file!")
Packit 1c1d7e
		print(" */")
Packit 1c1d7e
		print("#include \"configvalues.h\"")
Packit 1c1d7e
		print("#include \"configimpl.h\"")
Packit 1c1d7e
		print("")
Packit 1c1d7e
		print("ConfigValues::ConfigValues() : m_map(257)")
Packit 1c1d7e
		print("{")
Packit 1c1d7e
		print("  m_map.setAutoDelete(TRUE);")
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "group"):
Packit 1c1d7e
					parseGroupMapInit(n)
Packit 1c1d7e
		print("}")
Packit 1c1d7e
		print("")
Packit 1c1d7e
		print("void ConfigValues::init()")
Packit 1c1d7e
		print("{")
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "group"):
Packit 1c1d7e
					parseGroupInit(n)
Packit 1c1d7e
		print("}")
Packit 1c1d7e
	elif (sys.argv[1] == "-cpp"):
Packit 1c1d7e
		print("/* WARNING: This file is generated!")
Packit 1c1d7e
		print(" * Do not edit this file, but edit config.xml instead and run")
Packit 1c1d7e
		print(" * python configgen.py -cpp config.xml to regenerate this file!")
Packit 1c1d7e
		print(" */")
Packit 1c1d7e
		print("")
Packit 1c1d7e
		print("#include \"configoptions.h\"")
Packit 1c1d7e
		print("#include \"configimpl.h\"")
Packit 1c1d7e
		print("#include \"portable.h\"")
Packit 1c1d7e
		print("#include \"settings.h\"")
Packit 1c1d7e
		print("")
Packit 1c1d7e
		print("void addConfigOptions(ConfigImpl *cfg)")
Packit 1c1d7e
		print("{")
Packit 1c1d7e
		print("  ConfigString *cs;")
Packit 1c1d7e
		print("  ConfigEnum   *ce;")
Packit 1c1d7e
		print("  ConfigList   *cl;")
Packit 1c1d7e
		print("  ConfigInt    *ci;")
Packit 1c1d7e
		print("  ConfigBool   *cb;")
Packit 1c1d7e
		print("")
Packit 1c1d7e
		# process header
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "header"):
Packit 1c1d7e
					parseHeader(n,'cfg')
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "group"):
Packit 1c1d7e
					parseGroups(n)
Packit 1c1d7e
		print("}")
Packit 1c1d7e
	elif (sys.argv[1] == "-wiz"):
Packit 1c1d7e
		print("/* WARNING: This file is generated!")
Packit 1c1d7e
		print(" * Do not edit this file, but edit config.xml instead and run")
Packit 1c1d7e
		print(" * python configgen.py -wiz config.xml to regenerate this file!")
Packit 1c1d7e
		print(" */")
Packit 1c1d7e
		print("#include \"configdoc.h\"")
Packit 1c1d7e
		print("#include \"docintf.h\"")
Packit 1c1d7e
		print("")
Packit 1c1d7e
		print("void addConfigDocs(DocIntf *doc)")
Packit 1c1d7e
		print("{")
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "header"):
Packit 1c1d7e
					parseHeader(n,'doc')
Packit 1c1d7e
		for n in elem.childNodes:
Packit 1c1d7e
			if n.nodeType == Node.ELEMENT_NODE:
Packit 1c1d7e
				if (n.nodeName == "group"):
Packit 1c1d7e
					parseGroupCDocs(n)
Packit 1c1d7e
		print("}")
Packit 1c1d7e
Packit 1c1d7e
if __name__ == '__main__':
Packit 1c1d7e
	main()