From a0e23f824f8865cb1d3eb7808a3107c7864b579a Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Sat, 4 May 2013 00:01:09 +0200 Subject: - started to implement new XML tools - prepared introduction of SCons XSD namespace --- bin/SConsDoc.py | 421 ++++++++++++---------- bin/docs-update-generated.py | 48 +++ bin/docs-validate.py | 17 + bin/scons-proc.py | 357 ++++++------------- doc/SConscript | 9 - doc/scons.mod | 714 +++++++++++++++++++------------------ src/engine/SCons/Tool/qt.xml | 8 +- src/engine/SCons/Tool/xgettext.xml | 4 +- 8 files changed, 771 insertions(+), 807 deletions(-) create mode 100644 bin/docs-update-generated.py create mode 100644 bin/docs-validate.py diff --git a/bin/SConsDoc.py b/bin/SConsDoc.py index 4927dc0..8889923 100644 --- a/bin/SConsDoc.py +++ b/bin/SConsDoc.py @@ -112,7 +112,173 @@ import imp import os.path import re import sys -import xml.sax.handler + +# Do we have libxml2/libxslt/lxml? +has_libxml2 = True +has_lxml = True +try: + import libxml2 + import libxslt +except: + has_libxml2 = False +try: + import lxml +except: + has_lxml = False + + +re_entity = re.compile("\&([^;]+);") + +entity_header = """ +%scons; + +%builders-mod; + +%functions-mod; + +%tools-mod; + +%variables-mod; +]>""" + +# Namespace for the SCons Docbook XSD +dbxsd="http://www.scons.org/dbxsd/v1.0" + +xml_header = """ + + +%s + + +""" % (entity_header, dbxsd) + +def remove_entities(content): + # Cut out entity inclusions + content = content.replace(entity_header, "") + # Cut out entities themselves + content = re_entity.sub(lambda match: match.group(1), content) + + return content + +default_xsd = os.path.join('doc','xsd','scons.xsd') + +def validate_xml(fpath, xmlschema_context): + if not has_libxml2: + # At the moment we prefer libxml2 over lxml, the latter can lead + # to conflicts when installed together with libxml2. + if has_lxml: + # Use lxml + from lxml import etree + xmlschema = etree.XMLSchema(xmlschema_context) + doc = etree.parse(fpath) + try: + xmlschema.assertValid(doc) + except: + return False + return True + else: + # Try xmllint as a last fallback + try: + import subprocess + p = subprocess.Popen(['xmllint','--noout','--noent','--schema',default_xsd,fpath], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + sout, serr = p.communicate() + if serr and not 'validates' in serr: + print serr + return False + + return True + + except: + print "Can't validate %s! Neither lxml/libxml2, nor xmllint found." % fpath + return False + + # Read file and resolve entities + doc = libxml2.readFile(fpath, None, libxml2.XML_PARSE_NOENT) + err = xmlschema_context.schemaValidateDoc(doc) + # Cleanup + doc.freeDoc() + + if err: + # TODO: print error message "Haha",err + return False + + return True + +perc="%" + +def validate_all_xml(dpath='src', xsdfile=default_xsd): + xmlschema_context = None + if not has_libxml2: + # At the moment we prefer libxml2 over lxml, the latter can lead + # to conflicts when installed together with libxml2. + if has_lxml: + # Use lxml + from lxml import etree + xmlschema_context = etree.parse(xsdfile) + else: + # Use libxml2 and prepare the schema validation context + ctxt = libxml2.schemaNewParserCtxt(xsdfile) + schema = ctxt.schemaParse() + del ctxt + xmlschema_context = schema.schemaNewValidCtxt() + + fpaths = [] + for path, dirs, files in os.walk(dpath): + for f in files: + if f.endswith('.xml'): + fp = os.path.join(path, f) + fpaths.append(fp) + + fails = [] + for idx, fp in enumerate(fpaths): + fpath = os.path.join(path, f) + print "%.2f%s (%d/%d) %s" % (float(idx+1)*100.0/float(len(fpaths)), + perc, idx+1, len(fpaths),fp) + + if not validate_xml(fp, xmlschema_context): + fails.append(fp) + continue + + if has_libxml2: + # Cleanup + del xmlschema_context + del schema + + if fails: + return False + + return True + +try: + from lxml import etree +except ImportError: + try: + # Python 2.5 + import xml.etree.cElementTree as etree + except ImportError: + try: + # Python 2.5 + import xml.etree.ElementTree as etree + except ImportError: + try: + # normal cElementTree install + import cElementTree as etree + except ImportError: + try: + # normal ElementTree install + import elementtree.ElementTree as etree + except ImportError: + print("Failed to import ElementTree from any known place") + sys.exit(1) class Item(object): def __init__(self, name): @@ -121,8 +287,8 @@ class Item(object): if self.sort_name[0] == '_': self.sort_name = self.sort_name[1:] self.summary = [] - self.sets = None - self.uses = None + self.sets = [] + self.uses = [] def cmp_name(self, name): if name[0] == '_': name = name[1:] @@ -175,201 +341,78 @@ class Arguments(object): def append(self, data): self.body.append(data) -class Summary(object): +class SConsDocHandler(object): def __init__(self): - self.body = [] - self.collect = [] - def append(self, data): - self.collect.append(data) - def end_para(self): - text = ''.join(self.collect) - paras = text.split('\n\n') - if paras == ['\n']: - return - if paras[0] == '': - self.body.append('\n') - paras = paras[1:] - paras[0] = '\n' + paras[0] - if paras[-1] == '': - paras = paras[:-1] - paras[-1] = paras[-1] + '\n' - last = '\n' - else: - last = None - sep = None - for p in paras: - c = Chunk("para", p) - if sep: - self.body.append(sep) - self.body.append(c) - sep = '\n' - if last: - self.body.append(last) - def begin_chunk(self, chunk): - self.end_para() - self.collect = chunk - def end_chunk(self): - self.body.append(self.collect) - self.collect = [] - -class SConsDocHandler(xml.sax.handler.ContentHandler, - xml.sax.handler.ErrorHandler): - def __init__(self): - self._start_dispatch = {} - self._end_dispatch = {} - keys = list(self.__class__.__dict__.keys()) - start_tag_method_names = [k for k in keys if k[:6] == 'start_'] - end_tag_method_names = [k for k in keys if k[:4] == 'end_'] - for method_name in start_tag_method_names: - tag = method_name[6:] - self._start_dispatch[tag] = getattr(self, method_name) - for method_name in end_tag_method_names: - tag = method_name[4:] - self._end_dispatch[tag] = getattr(self, method_name) - self.stack = [] - self.collect = [] - self.current_object = [] self.builders = {} self.functions = {} self.tools = {} self.cvars = {} - def startElement(self, name, attrs): - try: - start_element_method = self._start_dispatch[name] - except KeyError: - self.characters('<%s>' % name) - else: - start_element_method(attrs) + def parseText(self, root): + txt = "" + for e in root.childNodes: + if (e.nodeType == e.TEXT_NODE): + txt += e.data + return txt - def endElement(self, name): - try: - end_element_method = self._end_dispatch[name] - except KeyError: - self.characters('' % name) - else: - end_element_method() - - # - # - def characters(self, chars): - self.collect.append(chars) - - def begin_collecting(self, chunk): - self.collect = chunk - def end_collecting(self): - self.collect = [] - - def begin_chunk(self): - pass - def end_chunk(self): - pass - - # - # - # - - def begin_xxx(self, obj): - self.stack.append(self.current_object) - self.current_object = obj - def end_xxx(self): - self.current_object = self.stack.pop() - - # - # - # - def start_scons_doc(self, attrs): - pass - def end_scons_doc(self): - pass - - def start_builder(self, attrs): - name = attrs.get('name') - try: - builder = self.builders[name] - except KeyError: - builder = Builder(name) - self.builders[name] = builder - self.begin_xxx(builder) - def end_builder(self): - self.end_xxx() - - def start_scons_function(self, attrs): - name = attrs.get('name') - try: - function = self.functions[name] - except KeyError: - function = Function(name) - self.functions[name] = function - self.begin_xxx(function) - def end_scons_function(self): - self.end_xxx() - - def start_tool(self, attrs): - name = attrs.get('name') - try: - tool = self.tools[name] - except KeyError: - tool = Tool(name) - self.tools[name] = tool - self.begin_xxx(tool) - def end_tool(self): - self.end_xxx() - - def start_cvar(self, attrs): - name = attrs.get('name') + def parseItems(self, domelem): + items = [] + + for i in domelem.iterchildren(tag="item"): + items.append(self.parseText(i)) + + return items + + def parseUsesSets(self, domelem): + uses = [] + sets = [] + + for u in domelem.iterchildren(tag="uses"): + uses.extend(self.parseItems(u)) + for s in domelem.iterchildren(tag="sets"): + sets.extend(self.parseItems(s)) + + return sorted(uses), sorted(sets) + + def parseInstance(self, domelem, map, Class): + name = domelem.attrib.get('name','unknown') try: - cvar = self.cvars[name] + instance = map[name] except KeyError: - cvar = ConstructionVariable(name) - self.cvars[name] = cvar - self.begin_xxx(cvar) - def end_cvar(self): - self.end_xxx() - - def start_arguments(self, attrs): - arguments = Arguments(attrs.get('signature', "both")) - self.current_object.arguments.append(arguments) - self.begin_xxx(arguments) - self.begin_collecting(arguments) - def end_arguments(self): - self.end_xxx() - - def start_summary(self, attrs): - summary = Summary() - self.current_object.summary = summary - self.begin_xxx(summary) - self.begin_collecting(summary) - def end_summary(self): - self.current_object.end_para() - self.end_xxx() - - def start_example(self, attrs): - example = Chunk("programlisting") - self.current_object.begin_chunk(example) - def end_example(self): - self.current_object.end_chunk() - - def start_uses(self, attrs): - self.begin_collecting([]) - def end_uses(self): - self.current_object.uses = sorted(''.join(self.collect).split()) - self.end_collecting() - - def start_sets(self, attrs): - self.begin_collecting([]) - def end_sets(self): - self.current_object.sets = sorted(''.join(self.collect).split()) - self.end_collecting() - - # Stuff for the ErrorHandler portion. - def error(self, exception): - linenum = exception._linenum - self.preamble_lines - sys.stderr.write('%s:%d:%d: %s (error)\n' % (self.filename, linenum, exception._colnum, ''.join(exception.args))) - - def fatalError(self, exception): - linenum = exception._linenum - self.preamble_lines - sys.stderr.write('%s:%d:%d: %s (fatalError)\n' % (self.filename, linenum, exception._colnum, ''.join(exception.args))) + instance = Class(name) + map[name] = instance + uses, sets = self.parseUsesSets(domelem) + instance.uses.extend(uses) + instance.sets.extend(sets) + # Parse summary and function blobs + + def parseDomtree(self, root): + # Process Builders + for b in root.iterchildren(tag="{%s}builder" % dbxsd): + self.parseInstance(b, self.builders, Builder) + # Process Functions + for f in root.iterchildren(tag="{%s}scons_function" % dbxsd): + self.parseInstance(f, self.functions, Function) + # Process Tools + for t in root.iterchildren(tag="{%s}tool" % dbxsd): + self.parseInstance(t, self.tools, Tool) + # Process CVars + for c in root.iterchildren(tag="{%s}cvar" % dbxsd): + self.parseInstance(c, self.cvars, ConstructionVariable) + + def parseContent(self, content, include_entities=True): + if not include_entities: + content = remove_entities(content) + # Create domtree from given content string + root = etree.fromstring(content) + # Parse it + self.parseDomtree(root) + + def parseXmlFile(self, fpath): + # Create domtree from file + domtree = etree.parse(fpath) + # Parse it + self.parseDomtree(domtree.getroot()) def set_file_info(self, filename, preamble_lines): self.filename = filename diff --git a/bin/docs-update-generated.py b/bin/docs-update-generated.py new file mode 100644 index 0000000..2a78b9f --- /dev/null +++ b/bin/docs-update-generated.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# +# Searches through the whole source tree and updates +# the generated *.gen/*.mod files in the docs folder, keeping all +# documentation for the tools, builders and functions... +# as well as the entity declarations for them. +# Uses scons-proc.py under the hood... +# + +import os + +# Directory where all generated files are stored +gen_folder = 'doc/generated' + +def argpair(key): + """ Return the argument pair *.gen,*.mod for the given key. """ + arg = '%s,%s' % (os.path.join(gen_folder,'%s.gen' % key), + os.path.join(gen_folder,'%s.mod' % key)) + + return arg + +def generate_all(): + """ Scan for XML files in the src directory and call scons-proc.py + to generate the *.gen/*.mod files from it. + """ + flist = [] + for path, dirs, files in os.walk('src'): + for f in files: + if f.endswith('.xml'): + fpath = os.path.join(path, f) + flist.append(fpath) + + if flist: + # Does the destination folder exist + if not os.path.isdir(gen_folder): + try: + os.makedirs(gen_folder) + except: + print "Couldn't create destination folder %s! Exiting..." % gen_folder + return + # Call scons-proc.py + os.system('python bin/scons-proc.py -b %s -f %s -t %s -v %s %s' % + (argpair('builders'), argpair('functions'), + argpair('tools'), argpair('variables'), ' '.join(flist))) + + +if __name__ == "__main__": + generate_all() diff --git a/bin/docs-validate.py b/bin/docs-validate.py new file mode 100644 index 0000000..2bc70a9 --- /dev/null +++ b/bin/docs-validate.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# +# Searches through the whole source tree and validates all +# documentation files against our own XSD in docs/xsd. +# Additionally, it rewrites all files such that the XML gets +# pretty-printed in a consistent way. This is done to ensure that +# merging and diffing doesn't get too hard when people start to +# use different XML editors... +# + +import SConsDoc + +if __name__ == "__main__": + if SConsDoc.validate_all_xml(): + print "OK" + else: + print "Validation failed! Please correct the errors above and try again." diff --git a/bin/scons-proc.py b/bin/scons-proc.py index 1f537c7..7a56a79 100644 --- a/bin/scons-proc.py +++ b/bin/scons-proc.py @@ -5,17 +5,15 @@ # This script creates formatted lists of the Builders, functions, Tools # or construction variables documented in the specified XML files. # -# Dependening on the options, the lists are output in either +# Depending on the options, the lists are output in either # DocBook-formatted generated XML files containing the summary text -# and/or .mod files contining the ENTITY definitions for each item, -# or in man-page-formatted output. +# and/or .mod files containing the ENTITY definitions for each item. # import getopt import os import re import string import sys -import xml.sax try: from io import StringIO # usable as of 2.6; takes unicode only except ImportError: @@ -27,28 +25,26 @@ import SConsDoc base_sys_path = [os.getcwd() + '/build/test-tar-gz/lib/scons'] + sys.path helpstr = """\ -Usage: scons-proc.py [--man|--xml] - [-b file(s)] [-f file(s)] [-t file(s)] [-v file(s)] +Usage: scons-proc.py [-b file(s)] [-f file(s)] [-t file(s)] [-v file(s)] [infile ...] Options: -b file(s) dump builder information to the specified file(s) -f file(s) dump function information to the specified file(s) -t file(s) dump tool information to the specified file(s) -v file(s) dump variable information to the specified file(s) - --man print info in man page format, each -[btv] argument - is a single file name - --xml (default) print info in SML format, each -[btv] argument - is a pair of comma-separated .gen,.mod file names + + Regard that each -[btv] argument is a pair of + comma-separated .gen,.mod file names. + """ opts, args = getopt.getopt(sys.argv[1:], "b:f:ht:v:", ['builders=', 'help', - 'man', 'xml', 'tools=', 'variables=']) + 'tools=', 'variables=']) buildersfiles = None functionsfiles = None -output_type = '--xml' toolsfiles = None variablesfiles = None @@ -60,55 +56,29 @@ for o, a in opts: elif o in ['-h', '--help']: sys.stdout.write(helpstr) sys.exit(0) - elif o in ['--man', '--xml']: - output_type = o elif o in ['-t', '--tools']: toolsfiles = a elif o in ['-v', '--variables']: variablesfiles = a -h = SConsDoc.SConsDocHandler() -saxparser = xml.sax.make_parser() -saxparser.setContentHandler(h) -saxparser.setErrorHandler(h) - -xml_preamble = """\ - - -""" - -xml_postamble = """\ - -""" - -for f in args: - _, ext = os.path.splitext(f) - if ext == '.py': - dir, _ = os.path.split(f) - if dir: - sys.path = [dir] + base_sys_path - module = SConsDoc.importfile(f) - h.set_file_info(f, len(xml_preamble.split('\n'))) - try: - content = module.__scons_doc__ - except AttributeError: - content = None +def parse_docs(args, include_entities=True): + h = SConsDoc.SConsDocHandler() + for f in args: + if include_entities: + try: + h.parseXmlFile(f) + except: + sys.stderr.write("error in %s\n" % f) + raise else: - del module.__scons_doc__ - else: - h.set_file_info(f, len(xml_preamble.split('\n'))) - content = open(f).read() - if content: - content = content.replace('&', '&') - # Strip newlines after comments so they don't turn into - # spurious paragraph separators. - content = content.replace('-->\n', '-->') - input = xml_preamble + content + xml_postamble - try: - saxparser.parse(StringIO(unicode(input))) - except: - sys.stderr.write("error in %s\n" % f) - raise + content = open(f).read() + if content: + try: + h.parseContent(content, include_entities) + except: + sys.stderr.write("error in %s\n" % f) + raise + return h Warning = """\ -Aegis"> -Ant"> -ar"> -as"> -Autoconf"> -Automake"> -bison"> -cc"> -Cons"> -cp"> -csh"> -f77"> -f90"> -f95"> -gas"> -gcc"> -g77"> -gXX"> -Jam"> -jar"> -javac"> -javah"> -latex"> -lex"> -m4"> -Make"> -Make++"> -pdflatex"> -pdftex"> -Python"> -ranlib"> -rmic"> -SCons"> -ScCons"> -sleep"> -swig"> -tar"> -tex"> -touch"> -yacc"> -zip"> +Aegis"> +Ant"> +ar"> +as"> +Autoconf"> +Automake"> +bison"> +cc"> +Cons"> +cp"> +csh"> +f77"> +f90"> +f95"> +gas"> +gcc"> +g77"> +gXX"> +Jam"> +jar"> +javac"> +javah"> +latex"> +lex"> +m4"> +Make"> +Make++"> +pdflatex"> +pdftex"> +Python"> +ranlib"> +rmic"> +SCons"> +ScCons"> +sleep"> +swig"> +tar"> +tex"> +touch"> +yacc"> +zip"> -Action"> -ActionBase"> -CommandAction"> -FunctionAction"> -ListAction"> -Builder"> -BuilderBase"> -CompositeBuilder"> -MultiStepBuilder"> -Job"> -Jobs"> -Serial"> -Parallel"> -Node"> -Node.FS"> -Scanner"> -Sig"> -Signature"> -Taskmaster"> -TimeStamp"> -Walker"> -Wrapper"> +Action"> +ActionBase"> +CommandAction"> +FunctionAction"> +ListAction"> +Builder"> +BuilderBase"> +CompositeBuilder"> +MultiStepBuilder"> +Job"> +Jobs"> +Serial"> +Parallel"> +Node"> +Node.FS"> +Scanner"> +Sig"> +Signature"> +Taskmaster"> +TimeStamp"> +Walker"> +Wrapper"> @@ -96,20 +96,20 @@ --> ---config"> ---debug=explain"> ---debug=findlibs"> ---debug=includes"> ---debug=prepare"> ---debug=presub"> ---debug=stacktrace"> ---implicit-cache"> ---implicit-deps-changed"> ---implicit-deps-unchanged"> ---profile"> ---taskmastertrace"> ---tree"> --Q"> +--config"> +--debug=explain"> +--debug=findlibs"> +--debug=includes"> +--debug=prepare"> +--debug=presub"> +--debug=stacktrace"> +--implicit-cache"> +--implicit-deps-changed"> +--implicit-deps-unchanged"> +--profile"> +--taskmastertrace"> +--tree"> +-Q"> -implicit_cache"> -implicit_deps_changed"> -implicit_deps_unchanged"> +implicit_cache"> +implicit_deps_changed"> +implicit_deps_unchanged"> @@ -129,16 +129,16 @@ --> -build"> -Makefile"> -Makefiles"> -scons"> -SConscript"> -SConstruct"> -Sconstruct"> -sconstruct"> -.sconsign"> -src"> +build"> +Makefile"> +Makefiles"> +scons"> +SConscript"> +SConstruct"> +Sconstruct"> +sconstruct"> +.sconsign"> +src"> @@ -149,149 +149,149 @@ --> -Add"> -AddMethod"> -AddPostAction"> -AddPreAction"> -AddOption"> -AddOptions"> -AddVariables"> -Alias"> -Aliases"> -AllowSubstExceptions"> -AlwaysBuild"> -Append"> -AppendENVPath"> -AppendUnique"> -BoolOption"> -BoolVariable"> -Build"> -CacheDir"> -Chmod"> -Clean"> -Clone"> -Command"> -Configure"> -Copy"> -Decider"> -Default"> -DefaultEnvironment"> -DefaultRules"> -Delete"> -Depends"> -Dir"> -Dump"> -Duplicate"> -Entry"> -EnumOption"> -EnumVariable"> -EnsurePythonVersion"> -EnsureSConsVersion"> -Environment"> -Execute"> -Exit"> -Export"> -File"> -FindFile"> -FindInstalledFiles"> -FindPathDirs"> -Finish"> -Flatten"> -GenerateHelpText"> -GetBuildFailures"> -GetBuildPath"> -GetLaunchDir"> -GetOption"> -Glob"> -Help"> -Ignore"> -Import"> -Install"> -InstallAs"> -Link"> -ListOption"> -ListVariable"> -Local"> -MergeFlags"> -Mkdir"> -Module"> -Move"> -NoClean"> -NoCache"> -Objects"> -Options"> -Variables"> -PackageOption"> -PackageVariable"> -ParseConfig"> -ParseDepends"> -ParseFlags"> -PathOption"> -PathOption.PathAccept"> -PathOption.PathExists"> -PathOption.PathIsDir"> -PathOption.PathIsDirCreate"> -PathOption.PathIsFile"> -PathVariable"> -PathVariable.PathAccept"> -PathVariable.PathExists"> -PathVariable.PathIsDir"> -PathVariable.PathIsDirCreate"> -PathVariable.PathIsFile"> -Precious"> -Prepend"> -PrependENVPath"> -PrependUnique"> -Progress"> -Replace"> -Repository"> -Requires"> -Return"> -RuleSet"> -Salt"> -SetBuildSignatureType"> -SetContentSignatureType"> -SetDefault"> -SetOption"> -SideEffect"> -SourceSignature"> -SourceSignatures"> -Split"> -Tag"> -TargetSignatures"> -Task"> -Touch"> -UnknownOptions"> -UnknownVariables"> +Add"> +AddMethod"> +AddPostAction"> +AddPreAction"> +AddOption"> +AddOptions"> +AddVariables"> +Alias"> +Aliases"> +AllowSubstExceptions"> +AlwaysBuild"> +Append"> +AppendENVPath"> +AppendUnique"> +BoolOption"> +BoolVariable"> +Build"> +CacheDir"> +Chmod"> +Clean"> +Clone"> +Command"> +Configure"> +Copy"> +Decider"> +Default"> +DefaultEnvironment"> +DefaultRules"> +Delete"> +Depends"> +Dir"> +Dump"> +Duplicate"> +Entry"> +EnumOption"> +EnumVariable"> +EnsurePythonVersion"> +EnsureSConsVersion"> +Environment"> +Execute"> +Exit"> +Export"> +File"> +FindFile"> +FindInstalledFiles"> +FindPathDirs"> +Finish"> +Flatten"> +GenerateHelpText"> +GetBuildFailures"> +GetBuildPath"> +GetLaunchDir"> +GetOption"> +Glob"> +Help"> +Ignore"> +Import"> +Install"> +InstallAs"> +Link"> +ListOption"> +ListVariable"> +Local"> +MergeFlags"> +Mkdir"> +Module"> +Move"> +NoClean"> +NoCache"> +Objects"> +Options"> +Variables"> +PackageOption"> +PackageVariable"> +ParseConfig"> +ParseDepends"> +ParseFlags"> +PathOption"> +PathOption.PathAccept"> +PathOption.PathExists"> +PathOption.PathIsDir"> +PathOption.PathIsDirCreate"> +PathOption.PathIsFile"> +PathVariable"> +PathVariable.PathAccept"> +PathVariable.PathExists"> +PathVariable.PathIsDir"> +PathVariable.PathIsDirCreate"> +PathVariable.PathIsFile"> +Precious"> +Prepend"> +PrependENVPath"> +PrependUnique"> +Progress"> +Replace"> +Repository"> +Requires"> +Return"> +RuleSet"> +Salt"> +SetBuildSignatureType"> +SetContentSignatureType"> +SetDefault"> +SetOption"> +SideEffect"> +SourceSignature"> +SourceSignatures"> +Split"> +Tag"> +TargetSignatures"> +Task"> +Touch"> +UnknownOptions"> +UnknownVariables"> -subst"> +subst"> -Message"> -Result"> -CheckCHeader"> -CheckCXXHeader"> -CheckFunc"> -CheckHeader"> -CheckLib"> -CheckLibWithHeader"> -CheckType"> -TryAction"> -TryBuild"> -TryCompile"> -TryLink"> -TryRun"> +Message"> +Result"> +CheckCHeader"> +CheckCXXHeader"> +CheckFunc"> +CheckHeader"> +CheckLib"> +CheckLibWithHeader"> +CheckType"> +TryAction"> +TryBuild"> +TryCompile"> +TryLink"> +TryRun"> -IndexError"> -NameError"> -str"> -zipfile"> +IndexError"> +NameError"> +str"> +zipfile"> -Cache"> +Cache"> @@ -301,11 +301,11 @@ --> -ARGLIST"> -ARGUMENTS"> -BUILD_TARGETS"> -COMMAND_LINE_TARGETS"> -DEFAULT_TARGETS"> +ARGLIST"> +ARGUMENTS"> +BUILD_TARGETS"> +COMMAND_LINE_TARGETS"> +DEFAULT_TARGETS"> @@ -315,16 +315,16 @@ --> -BUILDERMAP"> -COLOR"> -COLORS"> -CONFIG"> -CPPDEFINES"> -RELEASE"> -RELEASE_BUILD"> -SCANNERMAP"> -TARFLAGS"> -TARSUFFIX"> +BUILDERMAP"> +COLOR"> +COLORS"> +CONFIG"> +CPPDEFINES"> +RELEASE"> +RELEASE_BUILD"> +SCANNERMAP"> +TARFLAGS"> +TARSUFFIX"> @@ -334,9 +334,9 @@ --> -PATH"> -PYTHONPATH"> -SCONSFLAGS"> +PATH"> +PYTHONPATH"> +SCONSFLAGS"> @@ -346,16 +346,16 @@ --> -allowed_values"> -build_dir"> -map"> -ignorecase"> -options"> -exports"> -source"> -target"> -variables"> -variant_dir"> +allowed_values"> +build_dir"> +map"> +ignorecase"> +options"> +exports"> +source"> +target"> +variables"> +variant_dir"> @@ -365,8 +365,8 @@ --> -all"> -none"> +all"> +none"> @@ -376,33 +376,33 @@ --> -BuildDir"> -CFile"> -CXXFile"> -DVI"> -Jar"> -Java"> -JavaH"> -Library"> -Object"> -PCH"> -PDF"> -PostScript"> -Program"> -RES"> -RMIC"> -SharedLibrary"> -SharedObject"> -StaticLibrary"> -StaticObject"> -Substfile"> -Tar"> -Textfile"> -VariantDir"> -Zip"> +BuildDir"> +CFile"> +CXXFile"> +DVI"> +Jar"> +Java"> +JavaH"> +Library"> +Object"> +PCH"> +PDF"> +PostScript"> +Program"> +RES"> +RMIC"> +SharedLibrary"> +SharedObject"> +StaticLibrary"> +StaticObject"> +Substfile"> +Tar"> +Textfile"> +VariantDir"> +Zip"> -Make"> +Make"> @@ -413,49 +413,49 @@ --> -builder function"> -build action"> -build actions"> -builder method"> +builder function"> +build action"> +build actions"> +builder method"> -Configure Contexts"> -configure context"> +Configure Contexts"> +configure context"> -Construction Environment"> -Construction Environments"> -Construction environment"> -Construction environments"> -construction environment"> -construction environments"> +Construction Environment"> +Construction Environments"> +Construction environment"> +Construction environments"> +construction environment"> +construction environments"> -Construction Variable"> -Construction Variables"> -Construction variable"> -Construction variables"> -construction variable"> -construction variables"> +Construction Variable"> +Construction Variables"> +Construction variable"> +Construction variables"> +construction variable"> +construction variables"> -CPPPATH"> +CPPPATH"> -Dictionary"> +Dictionary"> -Emitter"> -emitter"> +Emitter"> +emitter"> -factory"> +factory"> -Generator"> -generator"> +Generator"> +generator"> -Nodes"> +Nodes"> -signature"> -build signature"> +signature"> +build signature"> -true"> -false"> +true"> +false"> -typedef"> +typedef"> -action="> -batch_key="> -cmdstr="> -exitstatfunc="> -strfunction="> -varlist="> +action="> +batch_key="> +cmdstr="> +exitstatfunc="> +strfunction="> +varlist="> -bar"> -common1.c"> -common2.c"> -custom.py"> -goodbye"> -goodbye.o"> -goodbye.obj"> -file.dll"> -file.in"> -file.lib"> -file.o"> -file.obj"> -file.out"> -foo"> -foo.o"> -foo.obj"> -hello"> -hello.c"> -hello.exe"> -hello.h"> -hello.o"> -hello.obj"> -libfile_a"> -libfile_so"> -new_hello"> -new_hello.exe"> -prog"> -prog1"> -prog2"> -prog.c"> -prog.exe"> -stdio.h"> +bar"> +common1.c"> +common2.c"> +custom.py"> +goodbye"> +goodbye.o"> +goodbye.obj"> +file.dll"> +file.in"> +file.lib"> +file.o"> +file.obj"> +file.out"> +foo"> +foo.o"> +foo.obj"> +hello"> +hello.c"> +hello.exe"> +hello.h"> +hello.o"> +hello.obj"> +libfile_a"> +libfile_so"> +new_hello"> +new_hello.exe"> +prog"> +prog1"> +prog2"> +prog.c"> +prog.exe"> +stdio.h"> -+"> -#"> ++"> +#"> -announce@scons.tigris.org"> -dev@scons.tigris.org"> -users@scons.tigris.org"> +announce@scons.tigris.org"> +dev@scons.tigris.org"> +users@scons.tigris.org"> + + + + diff --git a/src/engine/SCons/Tool/qt.xml b/src/engine/SCons/Tool/qt.xml index 7a55dad..0522f20 100644 --- a/src/engine/SCons/Tool/qt.xml +++ b/src/engine/SCons/Tool/qt.xml @@ -98,17 +98,17 @@ Environment(tools=['default','qt']) The qt tool supports the following operations: -Automatic moc file generation from header files. +Automatic moc file generation from header files. You do not have to specify moc files explicitly, the tool does it for you. However, there are a few preconditions to do so: Your header file must have the same filebase as your implementation file and must stay in the same directory. It must have one of the suffixes .h, .hpp, .H, .hxx, .hh. You can turn off automatic moc file generation by setting QT_AUTOSCAN to 0. See also the corresponding -&b-Moc(); +&b-Moc;() builder method. -Automatic moc file generation from cxx files. +Automatic moc file generation from cxx files. As stated in the qt documentation, include the moc file at the end of the cxx file. Note that you have to include the file, which is generated by the transformation ${QT_MOCCXXPREFIX}<basename>${QT_MOCCXXSUFFIX}, by default @@ -119,7 +119,7 @@ by setting QT_AUTOSCAN to 0. See also the corresponding &b-Moc; builder method. -Automatic handling of .ui files. +Automatic handling of .ui files. The implementation files generated from .ui files are handled much the same as yacc or lex files. Each .ui file given as a source of Program, Library or SharedLibrary will generate three files, the declaration file, the diff --git a/src/engine/SCons/Tool/xgettext.xml b/src/engine/SCons/Tool/xgettext.xml index 31f5819..045a574 100644 --- a/src/engine/SCons/Tool/xgettext.xml +++ b/src/engine/SCons/Tool/xgettext.xml @@ -158,12 +158,12 @@ message "Hello from ../a.cpp". When you reverse order in # SConstruct file in '0/1/po/' subdirectory env = Environment( tools = ['default', 'xgettext'] ) env.POTUpdate(XGETTEXTFROM = 'POTFILES.in', XGETTEXTPATH=['../../', '../']) - then the messages.pot will contain + +then the messages.pot will contain msgid "Hello from ../../a.cpp" line and not msgid "Hello from ../a.cpp". - -- cgit v0.12